【问题标题】:Are event handlers guaranteed to complete before AJAX callbacks are invoked?事件处理程序是否保证在调用 AJAX 回调之前完成?
【发布时间】:2012-04-17 10:46:33
【问题描述】:

假设我有一个对服务器进行两次 AJAX 调用的事件处理程序:

$("#foo").click(function(){ 
    $.get("bar", function(){ alert("Hello"); });
    $.get("baz", function(){ alert("World"); });
});

我意识到调用回调的顺序是不确定的,因为它取决于每个请求需要多长时间等。

但这是我的问题:是否可以保证在调用任一回调函数之前我会到达事件处理程序的末尾?我读过一个页面的所有 Javascript 都在一个线程中执行,所以我认为这意味着我的 click 事件处理程序保证在调用任何回调之前完成。

这是正确的吗?或者第一个请求可能已经完成并且第一个回调在我们到达事件处理程序结束之前执行?

【问题讨论】:

    标签: javascript ajax asynchronous


    【解决方案1】:

    是的,这是有保证的,你是对的 - 只有一个线程(暂时忽略 s)。当一段 JavaScript 代码执行(占用执行线程)并且 AJAX 回调到达(或任何其他 GUI 事件、超时等)时,它会排队等待直到执行线程空闲(当前代码段完成)。

    JavaScript 引擎永远不会中断正在运行的代码来处理传入事件 - 事件总是会在队列中轻轻等待。这就是为什么在执行 CPU 密集型代码时 GUI 似乎冻结的原因 - 没有处理任何事件。这也是同步 AJAX 请求不好的原因。

    另见

    【讨论】:

      【解决方案2】:

      是的,JavaScript 是单线程的,因此您的执行永远不会被抢占。

      异步回调和事件的工作方式相同; mousedown 的处理程序保证在 mouseup 的处理程序之前完成,即使您的 mousedown 处理程序需要 2 秒并且您立即松开鼠标。

      AJAX 回调也是如此,它被放入与等待处理的事件相同(种类)的队列中

      【讨论】:

        【解决方案3】:

        一个有趣的转折是用 $.get() 代替 $.get(),假设我们使用的是从其他地方获得的 Promise(即实际的异步调用是在其他地方进行的)(-为什么我们会遇到这种情况?好吧,也许我们有一个记忆查询功能。)

        现在如果使用 jQuery 承诺,如果已经解决,回调将被同步调用。这是一个问题吗?那要看你的要求了。如果是这样,那么您可以将回调代码包装在 setTimeout(cb, 0) 中。

        另一方面,如果您希望回调被抢占怎么办?见my examples here

        【讨论】:

        • @Juan Mendes,我也可能被指责没有真正回答这个问题:-(
        【解决方案4】:

        我意识到调用回调的顺序是不确定的,因为它取决于每个请求需要多长时间等。

        按照你写的方式是的.. 但是有一些方法可以组织和控制它.. 即延迟和承诺。

        这里有一个很好的概述:http://net.tutsplus.com/tutorials/javascript-ajax/wrangle-async-tasks-with-jquery-promises/

        正确使用它们将确保您不会遇到任何您似乎试图避免的问题。

        ** 正如@Juan 所指出的,这不是您提出的问题的黑白答案。我只是想为您指出不同的方向或方法来看待同一问题,以便您可以更明确地定义您的预期行为。

        【讨论】:

        • OP 没有询问异步任务是否按顺序返回
        • 不,他不是,但我是说如果他控制所有异步回调,那么他可能不会遇到他一开始就试图避免的问题。这似乎是为了确保一个处理程序在其他处理程序之前完成。
        • 我可能过度分析了他的问题,并为我从他的问题中暗示的问题提供了解决方案,但他可能只是好奇。
        • 问题是:点击处理程序触发AJAX请求,是否有可能在点击处理程序完成之前调用成功回调?这与跟踪/争论异步任务无关。您说的有道理,但由于它并没有真正回答问题,因此更有可能使 OP 感到困惑
        • 而不是确保您以正确的顺序编写代码,以便在正确的时间将处理程序发送到事件队列,这样一切都可以在不中断的情况下发生。只是试图将他指向正确的方向首先让事情更容易处理。 :) 我确实明白你的意思
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-14
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        相关资源
        最近更新 更多