如何在forEach循环中添加promise调用

时间:2017-03-02 14:20:51

标签: angularjs angular-promise

angular.forEach(data.rows, function(value, key){
    var cell = [];
    subId = 0;
    angular.forEach(vm.tableJson, function(value1, key1){       
        if(value1.Type != 'table'){
            if(key == 0){
                vm.columns.push(value1.Name);               
            }
            cell.push(value[value1.Settings[1].Value])
        }
        else{
            reportService.getInnerTableRecords(aaa).then(function(dataRes){ //server call
                angular.forEach(dataRes.rows, function(value2, key2){
                    //some code                     
                })
            })          
        }
    });

}); 

在上面的代码中forEach循环在从服务器获得响应之前完成。

如何使else案件等到答复?

由于 Chethan

2 个答案:

答案 0 :(得分:0)

您可以使用async之类的库来实现这一目标。

    async.mapSeries(data.rows, function(value, key, firstCallback){
        var cell = [];
        subId = 0;
        async.mapSeries(vm.tableJson, function(value1, key1, secondCallback){       
            if(value1.Type != 'table'){
                if(key == 0){
                    vm.columns.push(value1.Name);               
                }
                cell.push(value[value1.Settings[1].Value])
                secondCallback(null); // iterate next value1
            }
            else{
                reportService.getInnerTableRecords(aaa).then(function(dataRes){ //server call
                    angular.forEach(dataRes.rows, function(value2, key2){
                        //some code                     
                    });

                    secondCallback(null);// iterate next value1
                })          
            }
        }, function () {
            firstCallback(null); // all vm.tableJson completed. iterate next value of data.rows
        });

    }); 

async.mapSeries的迭代器将一直等到你调用secondCallback,然后转到vm.tableJson中的下一个项目,这样你就可以在收到服务器的响应后调用它。

答案 1 :(得分:0)

JavaScript是单线程的。在异步API解析结果之前,所有foreach循环都已完成。另一方面,foreach循环可以推送一系列承诺,可用于链接后续代码:

var promiseArray=[];

angular.forEach(vm.tableJson, function(value1, key1){       
    if(value1.Type != 'table'){
        if(key == 0){
            vm.columns.push(value1.Name);               
        }
        cell.push(value[value1.Settings[1].Value]);
        promiseArray.push(key1);
    }
    else{
        var promise = reportService.getInnerTableRecords(aaa);
        var newPromise = promise.then(function(dataRes){ //server call
            angular.forEach(dataRes.rows, function(value2, key2){
                //some code                     
            })
            return key1;
        });
        promiseArray.push(newPromise);          
    }
});

var compositePromise = $q.all(promiseArray);

return compositePromise.then(function(keyArray) {
    console.log("Number of processed keys = " + keyArray.length);
    //
    //Do subsequent processing here
}).catch(function(error) {
    console.error(error)
    throw error;
});

在上面的示例中,复合promise将解析为循环键的数组。循环的每次迭代都会将一个promise推送到一个数组。使用$q.all创建复合承诺。然后使用复合承诺链接后续代码。

请务必从嵌套级别返回promise。否则父承诺将在嵌套级别完成之前解决。

  

链接承诺

     

因为调用promise的.then方法会返回一个新的派生promise,所以很容易创建一个promise链。

     

可以创建任意长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。这使得实现强大的API成为可能。

     

--AngularJS $q Service API Reference -- Chaining Promises