Что будет, если написать await внутри forEach

Ответ

Использование await внутри forEach не будет работать ожидаемо, так как forEach не поддерживает асинхронные операции. Он просто запустит все колбэки параллельно и не дождётся их завершения.

Пример:

async function processItems(items) {
  items.forEach(async (item) => {
    await someAsyncFunction(item); // Не будет ожидаться
  });
  console.log('Done'); // Выполнится до завершения асинхронных операций
}

Решение:
Используйте for...of или Promise.all:

async function processItems(items) {
  for (const item of items) {
    await someAsyncFunction(item); // Корректное ожидание
  }
  console.log('Done'); // Выполнится после всех await
}

Ответ 18+ 🔞

О, смотри-ка, какой прикол! Сидишь ты такой, пишешь свой асинхронный код, всё красиво, async/await, модно-молодёжно. И думаешь: "А дай-ка я тут в forEach колбэк асинхронный засуну, пусть ждёт!"

И пишешь:

async function processItems(items) {
  items.forEach(async (item) => {
    await someAsyncFunction(item); // Не будет ожидаться
  });
  console.log('Done'); // Выполнится до завершения асинхронных операций
}

А потом запускаешь и такой: "Ёпта... А чё это 'Done' у меня в консоли вылезло раньше, чем все асинхронные функции отработали? Они же в await!"

А ларчик-то просто открывался, блядь! forEach — он тупой как пробка, сука. Он не про асинхронность, он про синхронный перебор. Он твой колбэк с async просто запустит и пойдёт дальше, не дожидаясь, пока тот там внутри всё await'ит. Он тебе все промисы запулит параллельно и смоется. А потом — бац! — и 'Done'. А твои асинхронные операции ещё где-то в другом измерении болтаются, ебать их в сраку.

Получается, ты хотел последовательно, а получил — "все сразу, а там как бог даст". Пиздец, да?

Что делать, чтобы не облажаться?
Да элементарно, Ватсон! Бери for...of и будет тебе счастье:

async function processItems(items) {
  for (const item of items) {
    await someAsyncFunction(item); // Корректное ожидание
  }
  console.log('Done'); // Выполнится после всех await
}

Вот теперь он будет честно ждать завершения каждой операции перед тем, как браться за следующую. Всё по-взрослому, без сюрпризов.

А если тебе не важен порядок, а надо просто всё запустить и дождаться, когда ВСЕ завершатся — тогда Promise.all в руки:

async function processItems(items) {
  await Promise.all(items.map(item => someAsyncFunction(item)));
  console.log('Done'); // Выполнится после всех промисов
}

Короче, запомни, как "Отче наш": forEach и async/await — хуй с горы, они не дружат. Не наступай на эти грабли, а то будешь потом дебажить, волнение ебать, а терпения-то ноль.