假设我有一个事件处理程序,它对服务器进行两次AJAX调用:
$("#foo").click(function(){
$.get("bar", function(){ alert("Hello"); });
$.get("baz", function(){ alert("World"); });
});
我意识到调用回调的顺序是不确定的,因为它取决于每个请求需要多长时间等。
但这是我的问题:是否保证在调用任何一个回调函数之前我将到达事件处理程序的末尾?我已经读过一个页面的所有Javascript都在一个线程中执行,所以我认为这意味着我的 click
保证在调用任何回调之前完成事件处理程序。
它是否正确?或者第一个请求是否可能完成并且在我们甚至到达事件处理程序结束之前执行了第一个回调?
是的,这是有保证的,你是对的 - 只有一个线程(忽略 网络工作者s暂时)。当一段JavaScript代码执行(占用执行线程)并且AJAX回调到达(或任何其他GUI事件,超时等)时,它会排队等待,直到执行线程空闲(当前代码完成)。
JavaScript引擎永远不会中断正在运行的代码来处理传入事件 - 事件将始终在队列中轻轻等待。这就是为什么在执行CPU密集型代码时GUI似乎冻结的原因 - 没有处理任何事件。这也是同步AJAX请求不好的原因。
也可以看看
是的,JavaScript是单线程的,因此您的执行永远不会被抢占。
异步回调和事件的工作方式相同;你的处理程序 mousedown
保证在你的处理程序之前完成 mouseup
,即使你的 mousedown
处理程序需要2秒钟,你让鼠标立即进入。
对于AJAX回调也是如此,它被放入与等待处理的事件相同的(类型)队列中
一个有趣的转折是代替$ .get(),假设我们使用的是我们从其他地方获得的承诺(即实际的异步调用是在其他地方进行的)( - 为什么我们会有这样的情况?好吧也许我们有一个memoized查询功能。)
现在,如果一个人正在使用jQuery promises,那么如果已经解决,则会同步调用回调。这是一个问题吗?那取决于你的要求。如果是,那么你可以将回调代码包装在一个 setTimeout(cb,0)。
另一方面,如果你想要回调被抢先怎么办?看到 我的例子在这里
是的,这是有保证的,你是对的 - 只有一个线程(忽略 网络工作者s暂时)。当一段JavaScript代码执行(占用执行线程)并且AJAX回调到达(或任何其他GUI事件,超时等)时,它会排队等待,直到执行线程空闲(当前代码完成)。
JavaScript引擎永远不会中断正在运行的代码来处理传入事件 - 事件将始终在队列中轻轻等待。这就是为什么在执行CPU密集型代码时GUI似乎冻结的原因 - 没有处理任何事件。这也是同步AJAX请求不好的原因。
也可以看看
是的,JavaScript是单线程的,因此您的执行永远不会被抢占。
异步回调和事件的工作方式相同;你的处理程序 mousedown
保证在你的处理程序之前完成 mouseup
,即使你的 mousedown
处理程序需要2秒钟,你让鼠标立即进入。
对于AJAX回调也是如此,它被放入与等待处理的事件相同的(类型)队列中
一个有趣的转折是代替$ .get(),假设我们使用的是我们从其他地方获得的承诺(即实际的异步调用是在其他地方进行的)( - 为什么我们会有这样的情况?好吧也许我们有一个memoized查询功能。)
现在,如果一个人正在使用jQuery promises,那么如果已经解决,则会同步调用回调。这是一个问题吗?那取决于你的要求。如果是,那么你可以将回调代码包装在一个 setTimeout(cb,0)。
另一方面,如果你想要回调被抢先怎么办?看到 我的例子在这里
我意识到调用回调的顺序是不确定的,因为它取决于每个请求需要多长时间等。
在你编写它的方式是的..但有一些方法来组织和控制这个...即deffereds和promises。
这是一个很好的概述: http://net.tutsplus.com/tutorials/javascript-ajax/wrangle-async-tasks-with-jquery-promises/
正确使用它们将确保您不会遇到您似乎试图避免的任何问题。
**
正如@Juan指出的那样,这不是你问的问题的黑白答案。我只是想指出你在不同的方向或方法来查看同一个问题,这样你就可以更明确地定义你的预期行为。