通常,我会使用传递给'jQuery.getJSON'函数的回调函数在服务器响应后执行某些操作。在这种情况下,我在某些输入元素上应用了事件处理程序,但这些处理程序只应在多个Ajax请求成功后才执行。基本上我需要暂停事件处理程序的执行,直到我期望的某些数据可用。如何同步JavaScript代码,这取决于多个Ajax请求的响应?
在多线程语言中,我会使用互斥锁/信号量来做到这一点,但由于JavaScript是单线程的,我不知道这样的事情是否可能。
通常,我会使用传递给'jQuery.getJSON'函数的回调函数在服务器响应后执行某些操作。在这种情况下,我在某些输入元素上应用了事件处理程序,但这些处理程序只应在多个Ajax请求成功后才执行。基本上我需要暂停事件处理程序的执行,直到我期望的某些数据可用。如何同步JavaScript代码,这取决于多个Ajax请求的响应?
在多线程语言中,我会使用互斥锁/信号量来做到这一点,但由于JavaScript是单线程的,我不知道这样的事情是否可能。
一个手动的方式来做到这一点是要排队的AJAX数组中的调用,然后计算您收到的回复的数量,并等待该计数与原始队列的大小相匹配(或者,在响应完成时将呼叫从队列中弹出,并且您知道在队列大小为0)。
你将不得不检查你是否准备好继续setTimeout调用。
或者,您可以在jQuery的退房递延支持1.5+
编辑:手动方法的快速和肮脏的例子:
var remoteCallA = function(){
$.getJSON('someurl', function(){
success++;
});
};
var remoteCallB = function(){
// etc
};
var whenAllDone = function(){
// do something when everything is done
};
var checkAllDone = function(){
if(success === remoteCalls.length){
whenAllDone();
}
else{
setTimeout(checkAllDone, 1000);
}
};
var remoteCalls = [remoteCallA, remoteCallB];
var success = 0;
for(var i = 0, length = remoteCalls.length; i++){
remoteCalls[i]();
}
checkAllDone();
javascript是基于事件的,所以一种方法是在每次协调xhr得到响应时抛出一个事件。事件处理程序跟踪响应,并且只有在全部返回时才会继续。
或者你也可以做同样的事情,而不活动,只要直接调用的方法和协调在那里的答复....
我可以给你一个肮脏的解决方案。一旦所有查询返回,创建你想要执行的函数。创建另一个函数来执行调度。就像信号/互斥一样,创建一个“同步”变量。增加每个呼叫的变量。然后,在调度函数中,递减变量,如果为零,则执行所需的函数。将调度函数应用为ajax返回的事件处理程序(如果您已有处理程序,而您不需要要暂停,请将其放在每个现有处理程序的末尾)。
然后,想一个更优雅的解决方案。
嗯,我感兴趣的'setTimeout'功能可能是我需要的。在你给出的例子中,假设你使用了一个小超时(比如20毫秒),这个递归会不会变得太深?它可能会导致堆栈溢出。 – 2011-05-20 18:28:58
@Thiado这实际上并不是递归,因为setTimeout()的调用会立即返回并退出函数。它只是告诉浏览器'嘿,在1000毫秒内运行'。 – Matt 2011-05-20 18:30:28
谢谢你,这正是我需要的:) – 2011-05-20 18:33:03