I have an array of Promises which I want to execute in parallel.
- I want to wait for all of them to settle before doing something
- 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.