0

I have an array of Promises which I want to execute in parallel.

  1. I want to wait for all of them to settle before doing something
  2. After all of them are settled, I want to take some action

I want to know if any of them are rejected. However, even when some of the promises are rejected I still want the others to be fulfilled.

Want to do this with built in Promises in ES6 and not with any special libraries like Q, When, WinJS, CO, etc.

Here is the concrete example. In this, I want to know that all 8 URLs from round1 completed (2 failed, 6 succeeded) before moving on to URLs in round2.

What happens is as soon as any of the promises is rejected, control moves on to the first catch block and keeps going through the chain of thens.

"use strict";

var request = require('request');
var util = require('util');

function getPage(url){
    return new Promise(function(resolve,reject){
        request(url, function(error, response, body){
            if(!error && response.statusCode == 200){
                let result = util.format('Done with %s, %d bytes', url, body.length);
                console.log(result);
                resolve(result);
            }
            else{
                reject(Error(error));
            }
        })
    });
}

let round1 = ['http://www.google.com', 'http://www.yahoo.com', 'http://www.nytimes.com', 'http://www.wsj.com', 'http://www.bad1ffsdwre.com', 'http://www.cnn.com', 'http://www.bad2ffsdwre.com', 'http://www.msnbc.com'];
let round2 = ['http://www.facebook.com', 'http://www.twitter.com', 'http://www.snapchat.com', 'http://www.instagram.com'];

Promise.all(round1.map(getPage))
    .then(function(results){
        console.log('Successfully completed Round1');       
    })
    .catch(function(error){
        console.log('there is an error in round 1: ', error);       
    })
    .then(function(){
        console.log('Done with Round 1')
    })
    .then(function(){
        Promise.all(round2.map(getPage))
            .then(function(results){
                console.log('Done with Round2');        
            })
            .catch(function(error){
                console.log('there is an error in round 2', error);     
            })          
    });

Actual Output:

node promises.js                                                                    
there is an error in round 1:  [Error: Error: getaddrinfo ENOTFOUND www.bad1ffsdwre.com www.bad1ffsdwre.com:80]    
Done with Round 1                                                                                                  
Done with http://www.google.com, 50085 bytes                                                                       
Done with http://www.cnn.com, 106541 bytes                                                                         
Done with http://www.snapchat.com, 6320 bytes                                                                      
Done with http://www.instagram.com, 14707 bytes                                                                    
Done with http://www.msnbc.com, 139798 bytes                                                                       
Done with http://www.facebook.com, 34710 bytes                                                                     
Done with http://www.nytimes.com, 177062 bytes                                                                     
Done with http://www.wsj.com, 827412 bytes                                                                         
Done with http://www.yahoo.com, 632892 bytes                                                                       
Done with http://www.twitter.com, 260178 bytes                                                                     
Done with Round2 

Desired Output:

node promises.js                                                                    
there is an error in round 1:  [Error: Error: getaddrinfo ENOTFOUND www.bad1ffsdwre.com www.bad1ffsdwre.com:80]    
Done with http://www.google.com, 50085 bytes                                                                       
Done with http://www.cnn.com, 106541 bytes                                                                         
Done with http://www.msnbc.com, 139798 bytes                                                                       
Done with http://www.nytimes.com, 177062 bytes                                                                     
Done with http://www.wsj.com, 827412 bytes                                                                         
Done with http://www.yahoo.com, 632892 bytes
there is an error in round 1:  [Error: Error: getaddrinfo ENOTFOUND www.bad2ffsdwre.com www.bad2ffsdwre.com:80]
Done with Round 1 
Done with http://www.snapchat.com, 6320 bytes                                                                      
Done with http://www.instagram.com, 14707 bytes                                                                    
Done with http://www.facebook.com, 34710 bytes                      
Done with http://www.twitter.com, 260178 bytes                                                                     
Done with Round2 

I am trying to learn the patterns in the plain ES6 Promises as outlined in this very excellent article. The author also mentions something similar in this quote at nearly the very end of the article.

Note: I'm unconvinced of Promise.race's usefulness; I'd rather have an opposite of Promise.all that only rejects if all items reject.

Amit Kulkarni
  • 910
  • 4
  • 11
  • Yes this is indeed a duplicate of this one:(http://stackoverflow.com/questions/31424561/wait-until-all-es6-promises-complete-even-rejected-promises). – Amit Kulkarni May 18 '16 at 17:11
  • For those inclined, here is the gist that has the solution to the specific example noted in the question: https://gist.github.com/arkulkarni/477bacef563166d639112f6ecd13f63a – Amit Kulkarni May 18 '16 at 17:25
  • Also here is another gist implementing the solution using generators and yield for reference: https://gist.github.com/arkulkarni/f9f3efb9f7b7c237a206755a4571d2d6 – Amit Kulkarni May 18 '16 at 20:42

0 Answers0