在循环中解析所有承诺后返回值

Return value after all promises are resolved within a loop

本文关键字:承诺 返回值 循环      更新时间:2024-02-09

给定此ID数组:

var array = [1,2,3,4,5];

在循环中进行的所有其他调用完成后,我如何返回promise?

            var deferred = $q.defer(),
                result = [];
            for (var i = 0; i < array.length; i++) {
                var id = array[i];
                Tools.remove(campaignID).then(function(result) {
                    result.push(result.id);
                }).catch(function (response) {
                    result.push(response)
                });
            }
            deferred.resolve(result);
            return deferred.promise;

您正在寻找等待promise数组的$q.all

我会这样做:

return $q.all(array.map(Tools.remove)).then(function(results){
    return results.map(function(result){ return result.id; });
});

其他答案实现了您已经从JavaScript或promise中免费获得的东西,并且大多具有反模式。

您只需将每个项目映射到Tools.remove,等待它-获取ID并返回它们。

我想你实际上并不想在所有任务完成后返回承诺,但解决了问题。

您可能需要实现一些自定义机制来跟踪未完成异步调用的数量。最简单的是一个简单的整数计数器:每次调度异步调用时递增,每次异步调用返回时递减。如果在返回时,任何异步调用都找到0,则可以断定这是最后一个返回的异步调用,并可以触发下一步的执行。

代码示例:

var asyncCount = 0;
for (var i = 0; i < array.length; i++) {
            var id = rows[i];
            asyncCount++;
            Tools.remove(campaignID).then(function(result) {
                result.push(result.id);
                asyncCount--;
                if(asyncCount === 0) nextStep();
            });
        }

如果您担心混合责任,可以将其转换为某种异步管理器类。

我会这样做:D

var arrayOfIds = [1,2,3,4,5];
var results = [];
var mySingleDeferred = new $.Deferred();
var arrayOfDeferreds = $.map(arrayOfIds, function(campaignID){       
    var deferredForThisOperation = Tools.remove(campaignID);
    deferredForThisOperation.done(function(result) {
       results.push(result.id);
    }).catch(function (response) {
       results.push(response)
    });  
    return deferredForThisOperation;
});
$.when(arrayOfDeferreds).then(function(){
    mySingleDeferred.resolve(results);
});
return mySingleDeferred.promise();