На примере фрагмента JavaScript с async/await и forEach: async function f(arr){ arr.forEach(async x=>await do(x)); } — объясните поведение и предложите вариант, который ждёт завершения всех do
Пояснение (кратко). В вашем примере: async function f(arr){ arr.forEach(async x => await do(x)); } метод forEach вызывает асинхронный callback для каждого элемента, но не ждёт возвращаемых им Promise. Поэтому f() завершает своё выполнение (возвращая Promise, который не ждёт внутренних do) до завершения всех do. Другими словами порождаются n=arr.lengthn = arr.lengthn=arr.length промисов, но они не агрегируются и не ожидаются. Варианты, которые ждут завершения всех do: 1) Параллельно (запускает все сразу, ждёт всех): async function f(arr){ await Promise.all(arr.map(x => do(x))); } // эквивалентно: await Promise.all(arr.map(do)); 2) Последовательно (ожидает по одному): async function f(arr){ for (const x of arr){ await do(x); } } Дополнительно: - Если нужно дождаться всех даже при ошибках, используйте Promise.allSettled\text{Promise.allSettled}Promise.allSettled: await Promise.allSettled(arr.map(do)); - Если нужен лимит параллелизма, примените библиотеку p-limit или реализуйте очередь.
async function f(arr){
arr.forEach(async x => await do(x));
}
метод forEach вызывает асинхронный callback для каждого элемента, но не ждёт возвращаемых им Promise. Поэтому f() завершает своё выполнение (возвращая Promise, который не ждёт внутренних do) до завершения всех do. Другими словами порождаются n=arr.lengthn = arr.lengthn=arr.length промисов, но они не агрегируются и не ожидаются.
Варианты, которые ждут завершения всех do:
1) Параллельно (запускает все сразу, ждёт всех):
async function f(arr){
await Promise.all(arr.map(x => do(x)));
}
// эквивалентно: await Promise.all(arr.map(do));
2) Последовательно (ожидает по одному):
async function f(arr){
for (const x of arr){
await do(x);
}
}
Дополнительно:
- Если нужно дождаться всех даже при ошибках, используйте Promise.allSettled\text{Promise.allSettled}Promise.allSettled:
await Promise.allSettled(arr.map(do));
- Если нужен лимит параллелизма, примените библиотеку p-limit или реализуйте очередь.