Skip to content

Instantly share code, notes, and snippets.

@jesstelford
Created April 27, 2015 04:35
Show Gist options
  • Save jesstelford/3cfd094c70024b378eb2 to your computer and use it in GitHub Desktop.
Save jesstelford/3cfd094c70024b378eb2 to your computer and use it in GitHub Desktop.
asyncSeries to ensure promises complete in correct order
/**
* Will execute success/fail in the order of the promises in the Iterable, even
* though they are executed in parallel.
*
* If `fail` is executed, no more promises in the series will be handled.
*
* @param promises An Iterable of Promises
* @param success a function which accepts the results of the promise
* @param fail a function which accepts the failure of the promise
*/
function asyncSeries(promises, success, fail) {
var iterator = promises[Symbol.iterator]();
nextPromise(iterator, success, fail);
function nextPromise(iterator, success, fail) {
var iteratorValue = iterator.next();
// our end-case for recursion is when the iterator is exhausted
if (!iteratorValue.done) {
// .value is the promise
iteratorValue.value.then(function() {
// Call the completion callback
success.apply(null, arguments);
// and recurse for the next promise in the array
nextPromise(iterator, success, fail);
}, fail);
}
}
}
/******
* EXAMPLE
*
* Two Promises are initiated, the first finishing in 600ms, the second finishing in 400ms.
* Executed in parallel, the second promise will resolve first.
* Using asyncSeries, the first promise will be resolved first, then the second.
* You can check this by the console output.
* You can also confirm the Promises are executed in parallel by the end time at which they resolve:
* In series, the largest end time should be 1000ms (600 + 400)
* In parallel, the largest end tiem should be 600.
******/
var startTime = +new Date();
var p1 = new Promise(function(resolve, result) {
setTimeout(function() {
resolve('first');
}, 600);
});
var p2 = new Promise(function(resolve, result) {
setTimeout(function() {
resolve('second');
}, 400);
});
asyncSeries([p1, p2], function(result) {
var endTime = +new Date();
console.log('result:', result);
console.log('time:', endTime - startTime);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment