我怎么能等待一系列异步回调函数? [英] How can I wait for set of asynchronous callback functions?

查看:152
本文介绍了我怎么能等待一系列异步回调函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有code,它看起来像这样在JavaScript:

I have code that looks something like this in javascript:

forloop {
    //async call, returns an array to its callback
}

所有这些异步调用的完成

之后,我想对所有的阵列来计算分。

After ALL of those async calls are done, I want to calculate the min over all of the arrays.

我如何可以等待它们全部?

How can I wait for all of them?

我唯一的想法,现在是有所谓的布尔做过一个数组,并设置完成[I]在第i个回调函数属实,然后说虽然(不是全部完成){}

My only idea right now is to have an array of booleans called done, and set done[i] to true in the ith callback function, then say while(not all are done) {}

编辑:我想一个可能的,但丑陋的解决方案,将是编辑在每个回调做阵列,然后调用一个方法,如果所有其他做从每个回调设置,而最后一个回调来完成将调用继续方法

edit: I suppose one possible, but ugly solution, would be to edit the done array in each callback, then call a method if all other done are set from each callback, thus the last callback to complete will call the continuing method.

先谢谢了。

推荐答案

您还没有非常具体与您的code,所以我会弥补的场景。比方说,你有10个Ajax调用,你想积累不同于10 Ajax调用的结果,然后当他们都完成你想要做的事。您可以在一个阵列积累的数据,并保持当最后一个已完成的轨道做这样的:

You haven't been very specific with your code, so I'll make up a scenario. Let's say you have 10 ajax calls and you want to accumulate the results from those 10 ajax calls and then when they have all completed you want to do something. You can do it like this by accumulating the data in an array and keeping track of when the last one has finished:

手动计数器

var ajaxCallsRemaining = 10;
var returnedData = [];

for (var i = 0; i < 10; i++) {
    doAjax(whatever, function(response) {
        // success handler from the ajax call

        // save response
        returnedData.push(response);

        // see if we're done with the last ajax call
        --ajaxCallsRemaining;
        if (ajaxCallsRemaining <= 0) {
            // all data is here now
            // look through the returnedData and do whatever processing 
            // you want on it right here
        }
    });
}

请注意:错误处理是很重要的位置(未显示,因为它是专门针对你如何让你的AJAX调用)。您将要想想你打算如何处理的情况下,当一个Ajax调用无法完成,无论是与错误或卡住了很长时间或超时很长一段时间了。

Note: error handling is important here (not shown because it's specific to how you're making your ajax calls). You will want to think about how you're going to handle the case when one ajax call never completes, either with an error or gets stuck for a long time or times out after a long time.

jQuery的诺言

添加到我的答案在2014年这些天,承诺经常被用来解决此类问题,因为jQuery的 $。阿贾克斯()已返回一个承诺, $时,()将让你知道当一群承诺全部解决,将收集的返回结果给你:

Adding to my answer in 2014. These days, promises are often used to solve this type of problem since jQuery's $.ajax() already returns a promise and $.when() will let you know when a group of promises are all resolved and will collect the return results for you:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
    // returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0]
    // you can process it here
}, function() {
    // error occurred
});


ES6标准少辉

添加到我在2015年的答案如果你有内置原生的承诺(现代浏览器或Node.js的或使用babeljs transpile或使用承诺填充工具)的环境中,那么你可以使用ES6指定的承诺。请参见的浏览器支持此表。承诺在pretty支持多目前所有的浏览器,除了IE浏览器。

Adding to my answer in 2015. If you have an environment with native promises built-in (modern browser or node.js or using babeljs transpile or using a promise polyfill), then you can use ES6-specified promises. See this table for browser support. Promises are supported in pretty much all current browsers, except IE.

如果 doAjax()返回一个承诺,那么你可以这样做:

If doAjax() returns a promise, then you can do this:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
    // returned data is in arguments[0], arguments[1], ... arguments[n]
    // you can process it here
}, function(err) {
    // error occurred
});


如果您需要一个非承诺异步​​操作成一个返回一个承诺,你可以在promisify这样的:


If you need to make a non-promise async operation into one that returns a promise, you can "promisify" it like this:

function doAjax(...) {
    return new Promise(function(resolve, reject) {
        someAsyncOperation(..., function(err, result) {
            if (err) return reject(err);
            resolve(result);
        });
    });
}

和,然后用上面的模式:

And, then use the pattern above:

var promises = [];
for (var i = 0; i < 10; i++) {
    promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
    // returned data is in arguments[0], arguments[1], ... arguments[n]
    // you can process it here
}, function(err) {
    // error occurred
});


蓝鸟承诺

如果您使用的是功能更丰富的库如href=\"http://bluebirdjs.com/docs/api-reference.html\" rel=\"nofollow\">蓝鸟承诺库,那么

If you use a more feature rich library such as the Bluebird promise library, then it has some additional functions built in to make this easier:

 var doAjax = Promise.promisify(someAsync);
 var someData = [...]
 Promise.map(someData, doAjax).then(function(results) {
     // all ajax results here
 }, function(err) {
     // some error here
 });

这篇关于我怎么能等待一系列异步回调函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆