2012-04-03 61 views
10

假设我有一个事件处理程序,一个将一对AJAX调用服务器:事件处理程序是否保证在调用AJAX回调之前完成?

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

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

但这里是我的问题:这是保证,我会任的回调函数之前到达我的事件处理程序结束时调用?我读过所有的JavaScript的网页在一个单独的线程来执行,所以我认为这意味着我click事件处理程序是保证完成任何回调都可以调用之前。

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

回答

10

是的,这是保证,你是对的 - 有单个线程(目前忽略)。当一块JavaScript代码执行的(占用的执行线程)和AJAX回调到达(或任何其他GUI事件,超时,等等)它被排队并等待,直到执行线程是免费的(当前代码段结束)。

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

4

是,JavaScript是单线程的,所以你的执行将永远不会被抢占。

异步回调和事件的工作方式相同;您的mousedown处理程序是保证您的处理程序之前完成了mouseup,即使你mousedown处理程序需要2秒钟就可以让鼠标马上去。

这同样适用于一个AJAX回调,它被放入同一个(种)队列的事件等待处理

0

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

在你写的方式是的,但有一些方法来组织和控制这个..即缓存和承诺。

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

正确使用它们将确保你不会碰到你似乎什么问题要尽量避免。

** 正如@Juan指出的那样,这并不是针对您问的问题的黑白答案。我只是试图用不同的方向或方法来看待同一问题,以便更明确地定义您的预期行为。

+1

OP没有询问异步任务返回的顺序 – 2012-04-03 19:18:44

+0

不是他不是,但我想说的是,如果他控制了所有异步回调,他可能不会遇到他试图避免的问题第一名。这似乎是要确保处理程序在其他处理程序之前完成。 – 2012-04-03 19:20:55

+0

“这是正确的吗?或者有可能第一个请求可能会完成,并且在我们甚至到达事件处理程序结束之前执行第一个回调?”如果它的编程方式明确,比他不会有这个问题,他会吗? – 2012-04-03 19:22:05

1

一个有趣的转折,这将是代替$获得(),可以说,我们使用,我们从别的地方(即实际的异步调用在别处制造)得到的承诺( - 为什么会我们有这样的情况?好吧,也许我们有一个记忆查询功能。)

现在,如果有人使用jQuery的承诺,如果已经解决,将会同步调用回调。这是否有问题?那么取决于你的要求。如果确实如此,则可以将回调代码包装在setTimeout(cb,0)中。

另一方面,如果您希望回调被抢先呢?请参阅my examples here

+0

@Juan Mendes,我可能会被指责没有真正回答这个问题:-( – 2013-04-25 00:23:42

相关问题