如何等待所有承诺,然后采取行动?

时间:2016-04-26 21:29:56

标签: javascript angularjs

我有一系列的承诺,我使用$ q.all来执行所有的承诺然后我做了一个动作,不知怎的,这个动作在承诺给出回答之前执行。

注意:flightAPIService.getNearestAirports()返回$ http angular:

  this.getNearestAirports = function (dataObj) {
    console.log('Client::flight service:: get the nearest '+ dataObj.maxAirports+' airport for lat: '+dataObj.lat+'lng:'+dataObj.lng);

    return $http.post('/getNearestAirports', dataObj);

    //// the result return in JSON format (Server converted the response from XML to JSON)
    //answer looks like:
    //{"airportResponse":{"$":{"authorisedAPI":"true","processingDurationMillis":"119","success":"true"},"airports":[{"airports":[{"$":{"city":"Tel-aviv","country":"Israel","lat":"32.011389","lng":"34.886667","name":"Ben Gurion","timezone":"Asia/Jerusalem"},"code":["TLV"]}]}]}}
};

当$ q.all执行promises(airportPromises)时,我预计打印表对象将在promises准备好之后出现,但实际上在promise之前打印的表已经回答:

  $q.all(airportPromises).finally(function(res){
            //return callback(null, table);
            console.log(table);
        },function(err){
            callback(err);
            return console.error('one promise error',err);
        })

这里所有的代码:

this.addAirportsToTable = function (table,callback) {
    var airportPromises = [];
   // var defered = $q.defer();
    this.whenFlightNeeded(table).then(function (result) {
        var table = result;
        for (let dayIndex = 0; dayIndex < table.length; dayIndex++) {
            if (table[dayIndex].flight.flight) {
                var origin = {
                    maxAirports: 3,
                    lat: table[dayIndex]['cityGoogleInf'][0].latitude,
                    lng: table[dayIndex]['cityGoogleInf'][0].longitude
                };
                var dist = {
                    maxAirports: 3,
                    lat: table[dayIndex + 1]['cityGoogleInf'][0].latitude,
                    lng: table[dayIndex + 1]['cityGoogleInf'][0].longitude
                };

                var promise1 = flightAPIService.getNearestAirports(origin).then(function (resultOriginAirport) {
                    table[dayIndex]['flight'].airport.push(resultOriginAirport.data);
                });

                var promise2 = flightAPIService.getNearestAirports(dist).then(function (resultDistAirport) {
                    table[dayIndex + 1]['flight'].airport.push(resultDistAirport.data);
                });

                airportPromises.concat([promise1,promise2]);
            }
        }
        $q.all(airportPromises).finally(function(res){
            //return callback(null, table);
            console.log(table);
        },function(err){
            callback(err);
            return console.error('one promise error',err);
        })
    });
    //return defered.promise;
}

知道如何确保完成所有承诺然后打印表吗?

在此屏幕截图中,我们可以看到对象表已打印,然后调试器再次返回以完成承诺任务: enter image description here

1 个答案:

答案 0 :(得分:3)

我认为问题出在concat

concat不会修改现有数组,但会返回一个新数组。所以你的调用$q.all传递一个空数组就会立即解决。

来自MDN

  

注意:连接数组/值将使原始文件保持不变。此外,对新阵列的任何操作都不会对原始阵列产生任何影响,反之亦然。

简单示例:https://jsfiddle.net/bunc6zg9/

在旁注$q.all上解析其等待的承诺值的数组。因此,如果您从两个承诺中返回.then中的表值,则可以在$.all中构建表格。这样,您的包含其状态的保证链就没有变量全局变量。