Хорошо, вернемся к прочтению статьи с более полным ответом. Эта тактика предназначена для асинхронных задач, которые зависят друг от друга, но не всегда одинаковы. Если бы они были фиксированной структурой, вы бы сделали (из примера):
return task1.then(result1 =>
task2.then(result2 =>
task3.then(result3 =>
[ result1, result2, result3 ]
)
)
).then(arrayOfResults => {
// Do something with all results
});
Думайте об этом с точки зрения выполнения, возможно, работы с базой данных.
return dbOrm.task1.create()
.then(newRecord =>
// task 2 requires the id from the new record to operate
dbOrm.task2.create({task1_id: newRecord.id})
.then(result2 =>
// some other async that relies on result2
task3(result2).then(result3 =>
[ result1, result2, result3 ]
)
)
).then(arrayOfResults => {
// Do something with all results
});
Это фиксированный набор зависимостей, они зависят друг от друга для работы, и для продолжения вам нужны результаты всех из них.
Пример, который вы связали, предназначен для такого последовательного выполнения, но в ситуации с нефиксированными зависимостями. Reduce используется для синхронного построения цепочки асинхронных действий, которые затем могут разрешаться самостоятельно, и, поскольку функция Reduce возвращает разрешенное обещание, вы можете связать другую функцию с конца для обработки завершенной цепочки.
Reduce - это больше, чем цикл forEach, хотя они оба используют итерацию для перемещения по массиву. Reduce также передает возвращенный результат предыдущей итерации следующей итерации. Вы «сокращаете» свою группу задач до одной выполненной задачи; forEach не действует для изменения массива, в котором он работает (а Map, другая итеративная функция массива, возвращает измененный новый массив из старого).
так, используя пример кода:
const tasks = getTaskArray();
return tasks.reduce((promiseChain, currentTask) => {
return promiseChain.then(chainResults =>
currentTask.then(currentResult =>
[ ...chainResults, currentResult ]
)
);
}, Promise.resolve([])).then(arrayOfResults => {
// Do something with all results
});
Вы бы получили что-то вроде этого, учитывая 2 итерации:
// 1
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
// 2
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
.then(chainResults => task2().then(task2Result => ([ ...chainResults, task2Result])
// the then after the reduce
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
.then(chainResults => task2().then(task2Result => ([ ...chainResults, task2Result])
.then(arrayOfResults => //do Something)
.catch(//because you should handle errors)