Promise.all() doesn't guarantee that promises will be resolved in order. How can this be done?
Asked
Active
Viewed 3,235 times
2 Answers
8
Since you're using Bluebird JS, this can be actually done in a simple way.
In version 2.0, Bluebird introduced the Promise.each
method that does this, for looping a then is simple enough, but since it is so common and got requested time after time eventually it was added as its own method.
function foo(item, ms){ // note bluebird has a delay method
return Promise.delay(ms, item).then(console.log.bind(console))
}
var items = ['one', 'two', 'three'];
Promise.each(items, function(item, i){
return foo(item, (items.length - i) * 1000)
});
Which produces the same result as the other answer, only with less lines of code and it also lets Bluebird perform optimizations on the iteration.

steampowered
- 11,809
- 12
- 78
- 98

Benjamin Gruenbaum
- 270,886
- 87
- 504
- 504
0
The thing that confused me most is that the async function being chained needs to return a function that returns a promise. Here's an example:
function setTimeoutPromise(ms) {
return new Promise(function (resolve) {
setTimeout(resolve, ms);
});
}
function foo(item, ms) {
return function() {
return setTimeoutPromise(ms).then(function () {
console.log(item);
});
};
}
var items = ['one', 'two', 'three'];
function bar() {
var chain = Promise.resolve();
items.forEach(function (el, i) {
chain = chain.then(foo(el, (items.length - i)*1000));
});
return chain;
}
bar().then(function () {
console.log('done');
});
Notice that foo returns a function that returns a promise. foo() does not return a promise directly.
See this Live Demo

redgeoff
- 3,163
- 1
- 25
- 39
-
Why are you returning a `chain.then()` when `then()` is called like that it effectively doesn't do anything but copy the promise. – Benjamin Gruenbaum Aug 16 '14 at 08:32
-
Benjamin's example is definitely simpler. I developed mine as I was dealing with the lie promise lib (https://github.com/calvinmetcalf/lie) in pouchdb in which case there isn't support for the each() call. My question should really have referenced liejs and not bluebirdjs :). – redgeoff Aug 16 '14 at 09:20
-
@BenjaminGruenbaum how else would you chain these promises using my code? I'm still learning the nuances of promises, so I'd appreciate your input. – redgeoff Aug 16 '14 at 09:21
-
`return chain` instead of `return chain.then()` – Benjamin Gruenbaum Aug 16 '14 at 09:26
-
Yup, missed that one :) – redgeoff Aug 16 '14 at 09:28
-
Also, `for .. in` loops do not guarantee iteration order, this can be result in an incorrect order in your case, you can use `items.forEach` or `for(var i = 0;...` instead – Benjamin Gruenbaum Aug 16 '14 at 09:29