Интенсивное чтение "Использование Reduce для последовательного выполнения Promise"

внешний интерфейс JavaScript Promise

1. Введение

Статьи, которые я прочитал на этой неделе,why-using-reduce-to-sequentially-resolve-promises-works, в котором описывается, как использовать сокращение для реализации последовательного выполнения промисов.

До появления async/await последовательное выполнение промисов было довольно проблематичным, и я надеюсь, что благодаря этой статье можно прояснить представление о последовательных промисах.

2 Обзор

помимо зависимостейasync promise-funи другие библиотеки инструментов, наиболее часто используемые операции с очередью:Array.prototype.reduce()сейчас:

let result = [1, 2, 5].reduce((accumulator, item) => {
  return accumulator + item;
}, 0); // <-- Our initial value.

console.log(result); // 8

Последнее значение 0 является начальным значением, и значение, возвращаемое каждым сокращением, будет использоваться в качестве первого параметра следующей функции обратного вызова сокращения до тех пор, пока цикл очереди не завершится, поэтому его можно будет накапливать.

тогда будетreduceИспользуйте свойства Promise, чтобы попробовать:

function runPromiseByQueue(myPromises) {
  myPromises.reduce(
    (previousPromise, nextPromise) => previousPromise.then(() => nextPromise()),
    Promise.resolve()
  );
}

Когда последнее обещание начинает выполняться (previousPromise.then), когда он закончит выполнение, вызовите следующий промис и верните его как новый промис, а следующая итерация продолжит цикл.

const createPromise = (time, id) => () =>
  new Promise(solve =>
    setTimeout(() => {
      console.log("promise", id);
      solve();
    }, time)
  );

runPromiseByQueue([
  createPromise(3000, 1),
  createPromise(2000, 2),
  createPromise(1000, 3)
]);

В результате получается:

promise 1
promise 2
promise 3

3 Интенсивное чтение

ReduceОн выполняется синхронно и будет завершен в цикле событий (подробнее см.Интенсивное чтение "Цикл событий и асинхронность JavaScript"), но это всего лишь быстрое построение очереди выполнения Promise в памяти, которая расширяется следующим образом:

new Promise((resolve, reject) => {
  // Promise #1

  resolve();
})
  .then(result => {
    // Promise #2

    return result;
  })
  .then(result => {
    // Promise #3

    return result;
  }); // ... and so on!

ReduceФункция состоит в том, чтобы сгенерировать эту очередь в памяти, без необходимости прописывать эту избыточную очередь в коде!

более простой способ

благодарныйeos3tionОдноклассники добавили, что с поддержкой async/await,runPromiseByQueueФункцию можно упростить еще больше:

async function runPromiseByQueue(myPromises) {
  for (let value of myPromises) {
    await value();
  }
}

Благодаря async/await код выглядит таким чистым и простым.

Заметим, однако, что эта идеяreduceОтличие состоит в том, что использованиеreduceВся функция является синхронной функцией, она строит очередь промисов после их выполнения, а затем выполняет их асинхронно в памяти, в то время как функция, использующая async/await, трансформируется в асинхронную функцию и ожидает выполнения каждого промиса.

Другие расширения промисов

дневная свиньяподелился с одноклассникамиpromise-funВ дополнение к последовательному решению Promise он также предоставляет ряд расширений функций Promise (некоторые из них постепенно внедряются в стандарт ES, напримерfinallyОн перешел в стадию 4), если ваш проект не может использовать async/await, вам не нужно переписывать его самостоятельно.Конечно, принцип этой статьи все еще нужно хорошо понимать.

Связанные со сценой могут быть расширены для чтенияИнтенсивное чтение "TC39 и предложение ECMAScript".

4 Резюме

Последовательные очереди промисов обычно мало используются, потому что последовательные блоки и взаимодействия с пользователем, как правило, параллельны. Так что для параллельных запросов фронтенд, получающий ответы в последовательном порядке, тоже интересная тема, о которой всем остается подумать.

еще 5 обсуждений

Адрес обсуждения:Интенсивное чтение «Последовательное выполнение обещаний с помощью сокращения» · Выпуск №109 · dt-fe/weekly

Если вы хотите принять участие в обсуждении, пожалуйста,кликните сюда, с новыми темами каждую неделю, выходящими по выходным или понедельникам. Интерфейс интенсивного чтения — поможет вам отфильтровать надежный контент.