如何同步依赖于多个ajax请求响应的javascript代码?

时间:2011-05-20 16:36:05

标签: javascript multithreading synchronization thread-safety

通常情况下,我会使用传递给'jQuery.getJSON'函数的回调函数在服务器响应后执行某些操作。在这种情况下,我在一些输入元素上应用了事件处理程序,但这些处理程序只应在多个ajax请求成功后执行。基本上我需要暂停执行事件处理程序,直到我期望的某些数据可用。

在多线程语言中,我会使用互斥锁/信号量,但由于javascript是单线程的,我想知道这样的事情是否可行。

3 个答案:

答案 0 :(得分:1)

javascript是基于事件的,因此一种方法是每次协调的xhr得到响应时抛出一个事件。事件处理程序跟踪响应,并且仅在返回所有响应时继续。

或者你可以在没有事件的情况下做同样的事情,只需直接调用方法并在那里协调响应....

答案 1 :(得分:1)

执行此操作的一种手动方法是将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();

答案 2 :(得分:1)

我可以给你一个肮脏的解决方案。所有查询返回后,创建要执行的功能。创建另一个函数来执行调度。就像信号量/互斥量一样,创建一个“同步”变量。增加每个调用的变量。然后,在dispatch函数中,递减变量,如果为零,则执行所需的函数。将调度函数应用为ajax返回的事件处理程序(如果已经有想要暂停的处理程序,则将其放在每个现有处理程序的末尾)。

然后,想一个更优雅的解决方案。