Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node JS Async Promise.All issues

I'm trying to execute an asynchronous routine for a bunch of items in a list that I get from a database, but I'm having trouble understanding how promise.all works and what it does.

Here is the code I'm using right now:

/**
 * Queues up price updates
 */
function updatePrices() {

     console.log("~~~ Now updating all listing prices from Amazon API ~~~");

    //Grabs the listings from the database, this part works fine    
    fetchListings().then(function(listings) {

        //Creates an array of promises from my listing helper class 
        Promise.all(listings.map(function(listing){

            //The promise that resolves to a response from the routine
            return(listing_helper.listingPriceUpdateRoutine(listing.asin));
        })).then(function(results){

            //We want to log the result of all the routine responses
            results.map(function(result){
                console.log(result);
            });

            //Let us know everything finished
            console.log("~~~ Listings updated ~~~");
        }).catch(function(err){
            console.log("Catch: ", err);
        });
    });
}

Right now, the only thing I get in the log is

~~~ Now updating all listing prices from Amazon API ~~~

I've tried adding a logging piece into the routine that is called and the routines all run successfully and log what they should, but promise.all.then doesn't execute.

I've tried just doing:

Promise.all(bleh).then(console.log("We did it"));

and that worked, but when I put a function in the Then, nothing runs.

Please help!

like image 423
user2172205 Avatar asked Apr 30 '16 17:04

user2172205


1 Answers

Promise.all() itself is pretty simple. You pass it an array of promises. It returns a new promise that will resolve when all the promises in your array resolve or will reject when any individual promise in the array rejects.

var pAll = Promise.all([p1, p2, p3]);

pAll.then(function(r) {
    // all promises resolved
    // r is an array of results
}, function(err) {
    // one or more promises rejected
    // err is the reason for the first promise that rejected
});

Some reasons that Promise.all() might not work in your code:

  1. You aren't passing an array of promises to it.
  2. Some of the promises in the array you pass never resolve or reject thus Promise.all() never resolves/rejects its master promise
  3. You aren't properly passing callbacks to .then() handlers where you should be
  4. You aren't properly returning promises from internal functions so they propagate out or chain properly

Your example:

Promise.all(bleh).then(console.log("We did it"));

Is wrong. You must pass a function reference to .then() like this:

Promise.all(bleh).then(function() {
    console.log("We did it")
});

In your case, the console.log() would execute immediately and not wait for the promises to be resolved.


In your detailed code are you 100% sure that:

listing_helper.listingPriceUpdateRoutine(listing.asin)

is returning a promise? And, that that promise will get resolved or rejected properly?


Note to Readers - If you read all the comments, you can see that the OP's actual issue was not with Promise.all(), but they were getting rate limited for sending requests too quickly to the target host. Since that should have been propagating a request error back which should have been easily visible, the OP apparently also has a problem with error handling or propagation which is likely in code that was not disclosed here.

like image 194
jfriend00 Avatar answered Sep 30 '22 17:09

jfriend00