Как я могу последовательно связать обещания, используя bluebirdjs?
Promise.all() не гарантирует, что обещания будут выполнены по порядку. Как это может быть сделано?
2 ответа
Поскольку вы используете Bluebird JS, на самом деле это можно сделать простым способом.
В версии 2.0 Bluebird представила Promise.each
метод, который делает это, для цикла затем достаточно прост, но так как он настолько распространен и получает запрошенный раз за разом, в конце концов он был добавлен как его собственный метод.
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)
});
Который дает тот же результат, что и другой ответ, только с меньшим количеством строк кода, а также позволяет Bluebird выполнять оптимизацию итерации.
Больше всего меня смутило то, что объединяемая асинхронная функция должна возвращать функцию, которая возвращает обещание. Вот пример:
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');
});
Обратите внимание, что foo возвращает функцию, которая возвращает обещание. foo() не возвращает обещание напрямую.
Посмотри это демо