多个ajax调用等待最后一个加载,然后执行

我有多个同时运行的ajax查询,我希望它们等待最后一个返回,然后在所有ajax调用上运行成功处理程序。 有关简化示例,请考虑:

$.ajax({//ajax call 1 url:page1.php, success: function(data1){ //do something with data1 } }); .... $.ajax({//ajax call 2 url:page2.php, success: function(data2){ //do something with data2 } }); //consider more than just two concurrent requests 

假设所有请求都是同时发送的。 由于它们是异步的,它们将在不同的时间返回。 假设一个请求需要100ms才能返回,另一个请求需要3000毫秒才能返回。 我显然不知道哪一个会先返回。 它们都以某种方式更新DOM,我希望在一次更新时一次性向观众显示这些更改。 我该怎么做呢?

我能想到的最好的方法是将data1和data2保存为全局变量。 然后有一个计数器变量,每次返回成功时都会计数。 然后,在counter == TOTAL_NUM_REQUESTS之后调用类似updateAll()的函数,然后运行所有全局变量并将它们放在需要的位置。 但这似乎很乱,容易出错。 加上那将是很多全局变量。

我理想的是让成功处理程序在返回时hibernate,然后在我将所有这些数据作为返回计数的情况下,向所有这些程序发送唤醒消息并且它们可以继续执行。 这似乎是最干净的,但我不知道在javascriptland中有这样的任何function。

有没有人对此有任何光鲜的想法?

答案更新

感谢李在下面,我得到了一个解决方案。 我的解决方案与他的下方类似。 我构建了一个分配给$ .ajax调用的async变量列表。 最初那些ajax调用的成功处理程序仍然被调用,所以我删除了它们并将它们放在另一个函数中, when我写的块when ,这个函数随后被调用。 我将results传递给了这样的函数:

 var results = []; results.push(async1); results.push(async2); ... for all the results ... $.when.apply(this, results).done(function() { for(var i=0;i<arguments.length;i++){ dataobject=arguments[i][0] if(dataobject.variousattribute) mySuccessHandlerFirstGuy(dataobject) else if(dataobject.anotherattribute) mySuccessHandlerSecondGuy(dataobject) //etc .... } }; 

参数对象花了一些时间来弄清楚它是什么。 这是一个2d数组(列表列表)。 第一个索引表示与给定的ajax请求相对应的返回对象。 它似乎是有序的,但最好让你的服务器返回你可以查找的东西并相应地写一个if / else块。 然后,在该给定元素中,该列表中似乎有3个元素。 第一个是从服务器返回的值,即您想要的值。 第二个是字符串success ,你可以用它来检查通话是否有效。 并且该列表中的第三个元素似乎是初始请求(尽管我不确定)。 这对我没用。

无论如何,我希望这有助于将来的某些人。 再次感谢李指出正确的方向。

所有ajax调用完成后,使用jQuery $ .when()函数运行:

jQuery.when docs

 var async1 = $.ajax({//ajax call 1 url:page1.php, success: function(data1){ //do something with data1 } }); .... var async2 = $.ajax({//ajax call 2 url:page2.php, success: function(data2){ //do something with data2 } }); $.when(async2, async1).done(function(result2, result1) { ... do this when both are successful ... }); 

在回答问题时添加:

如果你有一堆ajax调用你可以像这样使用’apply’:

 var results = []; results.push(async1); results.push(async2); ... for all the results ... $.when.apply(this, results).done(function() { ... use 'arguments' array to get results ... }); 

这可能与您已经提出的方式非常相似。

首先,创建全局变量var sleep = truevar request_count = 0 。 然后启动一个计时器,每隔一秒左右检查一次request_count与请求的总数。 然后,您的成功函数可以递增request_counter ,然后开始循环,直到sleep == false 。 然后,当通过计时器运行的监视function检测到request_count == TOTAL_REQUESTS它设置sleep = false ,并且您的所有成功函数将继续关于他们的业务。

一个简单的解决方案是使用PreloaderQ模块

https://www.npmjs.com/package/preloaderq

使用方法如下

 var preloader = new PreloaderQ() preloader.setEmptyCallback(function(){ //all tasks are finished }) preloader.setFirstTaskCallback(function(){ //started first task }) preloader.enqueueTask('ajax1') $.ajax({//ajax call 1 url:page1.php, success: function(data1){ prealoader.dequeueTask('ajax1') //do something with data1 } }); preloader.enqueueTask('ajax2') $.ajax({//ajax call 1 url:page2.php, success: function(data2){ prealoader.dequeueTask('ajax2') //do something with data2 } }); 

两个完成后将调用emptycallback