Как я могу последовательно связать обещания, используя 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() не возвращает обещание напрямую.

Посмотри это демо

Другие вопросы по тегам