javascript - Implementing Promise.series as alternative to Promise.all -
i saw example implementation of promise.all - runs promises in parallel - implementing promise.all
note functionality looking akin bluebird's promise.mapseries http://bluebirdjs.com/docs/api/mapseries.html
i making attempt @ creating promise.series, have seems work intended (it totally wrong, don't use it, see answers):
promise.series = function series(promises){ return new promise(function(resolve,reject){ const ret = promise.resolve(null); const results = []; promises.foreach(function(p,i){ ret.then(function(){ return p.then(function(val){ results[i] = val; }); }); }); ret.then(function(){ resolve(results); }, function(e){ reject(e); }); }); } promise.series([ new promise(function(resolve){ resolve('a'); }), new promise(function(resolve){ resolve('b'); }) ]).then(function(val){ console.log(val); }).catch(function(e){ console.error(e.stack); });
however, 1 potential problem implementation if reject promise, doesn't seem catch it:
promise.series([ new promise(function(resolve, reject){ reject('a'); // << reject here }), new promise(function(resolve){ resolve('b'); }) ]).then(function(val){ console.log(val); }).catch(function(e){ console.error(e.stack); });
does know why error doesn't caught , if there way fix promises?
according comment, made change:
promise.series = function series(promises){ return new promise(function(resolve,reject){ const ret = promise.resolve(null); const results = []; promises.foreach(function(p,i){ ret.then(function(){ return p.then(function(val){ results[i] = val; }, function(r){ console.log('rejected'); reject(r); // << handle rejected promises here }); }); }); ret.then(function(){ resolve(results); }, function(e){ reject(e); }); }); }
but still doesn't work expected...
the promise returned then
in foreach
loop not handle potential errors.
as pointed out in comment @slezica, try use reduce
rather foreach
, chains promises together.
promise.series = function series(promises) { const ret = promise.resolve(null); const results = []; return promises.reduce(function(result, promise, index) { return result.then(function() { return promise.then(function(val) { results[index] = val; }); }); }, ret).then(function() { return results; }); }
keep in mind promises "running" @ point though. if want run promises in series, should adjust function , pass in array of functions return promises. this:
promise.series = function series(providers) { const ret = promise.resolve(null); const results = []; return providers.reduce(function(result, provider, index) { return result.then(function() { return provider().then(function(val) { results[index] = val; }); }); }, ret).then(function() { return results; }); }