简体   繁体   中英

How to wait for all promises to be done then do an action?

I have an array of promises, I use $q.all to execute all the promises then I do an action, somehow this action executed before the promises give answer back.

note: flightAPIService.getNearestAirports() return $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"]}]}]}}
};

when the $q.all executes the promises (airportPromises) I expected that printing the table object will come after the promises are ready, but actually the table printed before the promise have answer:

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

Here all the code:

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;
}

Any idea how to make sure that all promises are done then to print the table?

in this screenshot we can see that the object table was printed then the debugger goes back again to finish the promise task: 在此输入图像描述

I believe the issue is your concat .

concat does not modify the existing array but returns a new one. So your calling $q.all passing it an empty array therefore is resolves instantly.

From the MDN :

Note: Concatenating array(s)/value(s) will leave the originals untouched. Furthermore, any operation on the new array will have no effect on the original arrays, and vice versa.

Quick example: https://jsfiddle.net/bunc6zg9/


On a side note $q.all resolves with an array of the values of the promises its waiting on. So if you returned your table values in the .then 's from your two promises you can build your table in the $.all 's then. That way you don't have a variable global to your promise chain containing its state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM