Создание собственной версии Promise.all

Обходите вход через for…of, сохраняя индекс каждого элемента. Счётчик с начальной единицей учитывает завершение самого обхода, включая пустой iterable.

Короткий ответ

Что ответить на собеседовании

Обходите вход через for…of, сохраняя индекс каждого элемента. Счётчик с начальной единицей учитывает завершение самого обхода, включая пустой iterable.

Подробный разбор

Ответ с пояснениями

Условие

Реализуйте функцию, которая воспроизводит поведение встроенного Promise.all. Функция принимает массив (или любой итерируемый объект) с промисами или обычными значениями и возвращает новый промис. Этот промис переходит в состояние fulfilled, когда все переданные элементы успешно завершились, и в состояние rejected при первой ошибке. Позиция элементов в результирующем массиве должна соответствовать их порядку во входных данных.

Ответ

Обходите вход через for…of, сохраняя индекс каждого элемента. Счётчик с начальной единицей учитывает завершение самого обхода, включая пустой iterable.

function all(iterable) {
  return new Promise((resolve, reject) => {
    const result = [];
    let remaining = 1, index = 0;
    for (const item of iterable) {
      const position = index++;
      remaining++;
      Promise.resolve(item).then(value => {
        result[position] = value;
        if (--remaining === 0) resolve(result);
      }, reject);
    }
    if (--remaining === 0) resolve(result);
  });
}

Подойдут массив, Set или генератор. Неитерируемый объект либо ошибка итератора отклонят итоговый Promise через исключение в executor. Порядок результатов сохраняется. Это аналог основного поведения, без полной поддержки произвольных конструкторов Promise и отмены операций.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее