Async-await и foreach() в узле
Несколько дней назад, когда я писал небольшой скрипт узла, я пытался загрузить изображения в итерации по массиву, поэтому я подумал об использовании foreach для итерации массива. При этом абстрактный код, который я написал, был следующим:
int i = 0; foreach(array, async (url) => { await download(url); i = i + 1; console.log(i, "image downloaded"); })
Во время выполнения я столкнулся с необычным поведением foreach(). Результатом кода было то, что значение i было напечатано без ожидания загрузки изображения. Я поискал об этом в Google и нашел альтернативу для... для которой async-await работал нормально.
Я начал копаться в функции foreach и прочитал, что foreach выполняется в стеке, а не в цикле событий, из-за чего асинхронная функция загрузки переходит в цикл событий, который возвращается после выполнения функции foreach в стеке. Когда стек очищается, функция из цикла событий возвращается в стек. альтернатива для… кода будет следующей:
async for(url of array) { await download(url); }
Чтобы узнать больше об этом, прочитайте полифилл foreach и map.