Самописный полифил для Promise.all

Создайте общий Promise и счётчик незавершённых входов. Каждый результат записывается по исходному индексу; первый rejection отклоняет общий Promise.

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

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

Создайте общий Promise и счётчик незавершённых входов. Каждый результат записывается по исходному индексу; первый rejection отклоняет общий Promise.

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

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

Условие

Напишите функцию promiseAll, имитирующую поведение встроенного Promise.all. Функция должна принимать массив промисов и возвращать новый промис, который будет выполнен успешно только когда выполнятся все переданные промисы, а в случае отклонения любого из них – сразу отклонится с тем же значением. Порядок результатов в массиве должен соответствовать порядку элементов входного массива.

function promiseAll(tasks: Promise<any>[]): Promise<any[]> {
  // ваш код тут
}

Ответ

Создайте общий Promise и счётчик незавершённых входов. Каждый результат записывается по исходному индексу; первый rejection отклоняет общий Promise.

function promiseAll(tasks) {
  return new Promise((resolve, reject) => {
    const values = Array(tasks.length);
    let remaining = tasks.length;
    if (!remaining) { resolve(values); return; }
    for (let index = 0; index < tasks.length; index++) {
      Promise.resolve(tasks[index]).then(value => {
        values[index] = value;
        if (--remaining === 0) resolve(values);
      }, reject);
    }
  });
}

Пустой массив разрешается в []. Promise.resolve также принимает обычные значения и thenable. Цикл по индексам не зависает на дырках массива, как forEach: они становятся undefined. Уже запущенные операции не отменяются при ошибке. Это реализация контракта массива, не полный generic-polyfill для произвольного iterable и подклассов Promise.

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

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

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

Подробнее