Promise.all() doesn't guarantee that promises will be resolved in order. How can this be done?
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.
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
来源:https://stackoverflow.com/questions/25338298/how-can-i-sequentially-chain-promises-using-bluebirdjs