Как переписать for на map для асинхронного кода?

Добрый день профессионалы! Вот такая загадка:
const list = [
  'main',
  'main-footer',
  'main-header',
  'main-content',
];

for (let i = 0; i < list.length; i++) {
      await funcOne(list[i]);
    }


функция funcOne асинхронная она переходит последовательно в каждый url и делает определенные вещи
async function funcOne(url) {
    await openFunc(url);
    ... и т.д.
  }


Как переписать цикл с помощью map чтобы тоже работало?
Пробовал вот так, но не работает
await Promise.all(list.map(async i => await funcOne(i)));
  • Вопрос задан
  • 1144 просмотра
Решения вопроса 2
Kozack
@Kozack Куратор тега JavaScript
Thinking about a11y
await Promise.all(list.map(funcOne)); // Если в случае ошибки в одной итерации нужно остановить все остальное

await Promise.allSettled(list.map(funcOne)); // Если в случае ошибки в одной итерации остальные должны продолжить работу


Но вы должны учитывать разницу:
  • Если использовать стандартный for то все асинхронные вызовы будут выполняться последовательно, один за другим.
  • Если вызывать асинхронную функцию в map, то все вызовы будут запущены параллельно, и итоговый Promise.all нужен, чтобы дождаться пока они все будут выполнены. Это эквивалентно примерно такому коду:
    const promises = []
    for (const item of list) {
          promises.push(funcOne(item));
    }
    await Promise.all(promises)

Ответ написан
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Именно с map никак не сделать, что бы следующий вызов функции ждал предыдущего, как это происходит в цикле с await, а вот с reduce уже можно:
const list = [
  'main',
  'main-footer',
  'main-header',
  'main-content',
];

list.reduce((p, item) => p.then(() => funcOne(item)), Promise.resolve());
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы