JQuery:每次异步后调用函数

例如,我们有这个代码:

$.each([1, 2, 3], function(key, val) { gear(val); }); function gear(params) { var values = {1: 'abc', 2: 'cba', 3: 'acb'}; query(values[params]); } function query(settings) { $.ajax({ ... settings ... }) } 

我怎么能等到每次迭代完成并调用一些东西呢?

您可以使用.reduce()来迭代数组,jQuery ajax承诺对函数调用进行排序:

 [1, 2, 3].reduce(function(p, item) { return p.then(function() { return gear(item); }); }, $.Deferred().resolve()).then(function() { // everything done here }); function gear(params) { var values = {1: 'abc', 2: 'cba', 3: 'acb'}; return query(values[params]); } function query(settings) { return $.ajax({ ... settings ... }) } 

这将对ajax调用进行排序,以便下一个调用在前一个调用完成之前不会启动。

gear()query() ,都返回$.ajax()已经返回的承诺。

然后,使用.reduce()迭代您累积promise的数组。 传入最初解析的promise,然后数组中的每个项都会在链的末尾添加.then()


如果您想同时运行所有Ajax调用,然后在完成所有操作后收到通知,则可以执行以下操作:

 $.when.apply($, [1, 2, 3].map(function(item) { return gear(item); })).then(function(r1, r2, r3) { // everything done here // results are in arguments[0], arguments[1], ... arguments[n] }); function gear(params) { var values = {1: 'abc', 2: 'cba', 3: 'acb'}; return query(values[params]); } function query(settings) { return $.ajax({ ... settings ... }) } 
 var deferreds = []; $.each([1, 2, 3], function(key, val) { gear(val); }); function gear(params) { var values = {1: 'abc', 2: 'cba', 3: 'acb'}; query(values[params]); } function query(settings) { deferreds.push($.ajax({ ... settings ... })); } $.when.apply($, deferreds).done(function(){ // do something here }); 

以下是实现它的一个例子。

 function iterate(callback) { $.each([1, 2, 3], function(key, val) { gear(val); }); callback(); } function gear(params) { var values = { 1: 'abc', 2: 'cba', 3: 'acb' }; print(values[params]); } function print(str) { document.write(str + "
") } function notifyComplete(){ print("Completed.") } iterate(notifyComplete);