Если вы предпочитаете методы, а не циклы (что я обычно делаю просто эстетически), вы можете добавить сторонний модуль, который я поддерживаю, который называется async-af
.
Среди прочего, онобеспечивает последовательный асинхронный интерфейс для каждого :
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
AsyncAF([0, 1, 2, 3, 4]).series.forEach(async () => {
console.log('waiting');
await sleep(1000);
});
<script src="https://unpkg.com/async-af@7.0.14/index.js"></script>
Конечно, вы также можете просто использовать простой for...of
цикл:
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
(async () => {
for (const _ of [0, 1, 2, 3, 4]) {
console.log('waiting');
await sleep(1000);
}
})();
Что касается , почему Array.prototype.forEach
не работает так, как вы ожидаете, возьмите эту чрезмерно упрощенную реализацию ( вот более полнаяодин ):
const forEach = (arr, fn) => {
for (let i = 0; i < arr.length; i++) {
// nothing is awaiting this function call
fn(arr[i], i, arr);
// i is then synchronously incremented and the next function is called
}
// return undefined
};
forEach([0, 1, 2, 3, 4], async () => {
console.log('waiting');
await delay(1000);
});
Как видите, Array.prototype.forEach
синхронно вызывает данную функцию обратного вызова для каждого элемента.Вот почему вы видите все пять waiting
журналов почти сразу.См. этот вопрос для получения дополнительной информации.