【问题标题】:jQuery $.ajax success firing last [duplicate]jQuery $.ajax 上次成功触发 [重复]
【发布时间】:2015-04-24 21:16:29
【问题描述】:

我有以下 Javascript,它返回的结果不符合我的预期。

function getCurrentItems(id){
    alert("2");
    $.ajax({
        url: "somePHPurlthatspitsoutajsonencodedArray.php",
        type: "POST",
        dataType: "json'",
        data: {id:id},
        success: function(data){
            alert("3");
        }
    });
    alert("4");
}

$(document).on('click', '.eventClass', function(e){
    alert("1");
    var id = "someID";
    var results = getCurrentItems(id);
    alert("5");
});

我想我会按 1、2、3、4、5 的顺序收到警报。

相反,我按 1、2、4、5、3 的顺序获取它们。

我只是不明白为什么成功警报 (5) 会最后触发?

【问题讨论】:

标签: javascript jquery ajax


【解决方案1】:

AJAX 是异步 JavaScript 和 XML 的缩写。异步是这里的关键词。我会用一个寓言来解释异步。

假设您正在手动洗碗。这样做时你不能做任何其他事情,所以它是同步的。

假设您将盘子放入洗碗机中。你可以做其他事情,你已经将任务委托给洗碗机,所以这是异步的。异步通常更好,因为您可以一次执行多项操作。 Javascript 仅在从服务器请求信息时异步,因为 Javascript 是单线程的(它只在 1 个 CPU 内核上运行,并且一次只能自己做一件事)。

回调是异步任务完成时调用的函数。洗碗机完成了,所以现在您必须在完成您正在做的事情后立即清空它。

因此,在您的代码中,您启动洗碗机,说您将在洗碗机完成运行时发出警报(“3”),然后您发出警报 4 和 5。然后当洗碗机完成时/您的服务器返回数据,你会像你说的那样提醒 3。

这有意义吗?

【讨论】:

  • 完美的解释,谢谢!
  • 不错的答案,但 Javascript 在发出请求时不仅是异步的。
  • 发出请求并不是 JS 唯一使用回调的时候,但它是 JS 唯一使用异步的时候。除非请求外部资源,否则 JS 无法异步运行。 @ecarrizo 是什么意思?
  • 试试这个,你就会明白这也是异步的 jsfiddle.net/zapqkpkz 还有其他方法可以处理这种行为,比如 promises 和 ita 不需要请求外部资源。事实上 ajax 是异步的,因为代码的编写方式不是为了代码正在做的事情
  • @ecarrizo 我不会考虑通过异步设置 setTimeout,但是是的,它和 setInterval 满足所有要求,很好。
【解决方案2】:

您在 ajax 请求中提供成功回调函数的原因是请求可能需要一些时间才能返回,但您的代码可以继续运行。在这种情况下,将发送 ajax 请求,并记住成功函数以供以后使用,然后您的代码将继续(警报 4 和 5)。当浏览器收到对 ajax 请求的响应时,它会调用成功函数(警报 3)。

Javascript 的工作方式是,每个浏览器选项卡只运行一个线程,因此在任何先前运行的代码完成之前不会调用事件处理程序。因此,即使您的 getCurrentItems 函数需要几秒钟才能完成,此时服务器响应已返回,直到您的函数完成后才会调用成功函数。

编辑:因为 ajax 调用可能需要一些时间,所以通常不希望能够调用像 getCurrentItems 这样包含 ajax 请求的函数并等待响应。如果你这样做,那么你很可能会让你的浏览器窗口没有响应,并且你将不得不处理来自 ajax 调用的潜在错误。相反,您应该将任何您希望运行的依赖于 ajax 结果的代码放入成功函数中,或者放入您从那里调用的另一个函数中。随着语言的发展,Javascript 非常适合做这种事情。您甚至可以将回调函数作为getCurrentItems 的参数,并从成功函数中运行它。

【讨论】:

    【解决方案3】:

    正如其他人所提到的,您将按照您看到的顺序获得结果,因为 ajax 请求不会返回其数据并调用您的成功回调,直到收到响应,但代码会在 $ 之后立即继续执行.ajax 调用。

    要获得您可能期望的工作流程,您可以使用 Promise,或者简单地传入回调:

    function getCurrentItems(id, onSuccess){
        alert("2");
        $.ajax({
            url: "somePHPurlthatspitsoutajsonencodedArray.php",
            type: "POST",
            dataType: "json'",
            data: {id:id},
            success: function(data){
                alert("3");
                onSuccess(data);
            }
        });
        alert("4");
    }
    
    $(document).on('click', '.eventClass', function(e){
        alert("1");
        var id = "someID";
        var results = getCurrentItems(id, function(data){
           console.log('data',data);
           alert("5");
        });
    
    });
    

    【讨论】:

    • 重新阅读问题
    • OP 知道发生了什么。他们在问为什么会发生这种情况。
    • ok,这将返回 1,2,4,3,5 中的结果。我专注于暗示他想要 5 最后一个结果的部分......也许我错过了其他东西?重新阅读这个问题并没有给我很多工作......
    • 这是解决他遇到的问题的解决方法,但他想知道为什么他会得到这个结果。如果您在解决方案之前添加解释,这将是一个可能的解决方法(您的代码建议)的问题的真正答案。
    • @ecarrizo 感谢您的反馈 - 我会添加更多细节。
    猜你喜欢
    • 1970-01-01
    • 2014-11-22
    • 2012-05-04
    • 2011-02-22
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多