First off you have to decide if you're running all your async operations in parallel or in sequence. If you launch all your operations in parallel, then all the requests are started at once and even though the first one fails, the others have already been sent so you can't stop them from being sent.
If you run your async operations in sequence where you issue one request and only once you get that response do you then run the next request, then you can stop any subsequent operations from being sent when one fails.
The code in your question, is launching all the requests in parallel because arr.map()
is synchronous (it runs through the entire array all at once). Thus when the first response comes back, all the other requests have already been sent so you can't stop them.
There are a number of ways you can sequence items from an array. One common design pattern that works for all Promise libraries is to use .reduce()
:
var arr = [{col1: 1}, {col2: 1}];
arr.reduce(function(p, val) {
return p.then(function() {
return indexingFunction(val);
});
}, Promise.resolve(result)).then(function() {
// all finished successfully
}, function(err) {
// finished with err
});
Bluebird also has some functions built in for working with collections:
Promise.map(arr, function(val) {
return indexingFunction(val);
}, {concurrency: 1}).all().then(function(results) {
// all results here
}, function(err) {
// error here
});
FYI, you may also want to see this: ES6 Promises - something like async.each?