Верните Promise, сохраните результаты по исходным индексам и считайте завершения. Первая ошибка отклоняет итоговый Promise; для пустого массива результат — [].
Самостоятельная реализация метода Promise.all (версия 3)
Верните Promise, сохраните результаты по исходным индексам и считайте завершения. Первая ошибка отклоняет итоговый Promise; для пустого массива результат — [].
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Требуется написать функцию, которая воспроизводит поведение стандартного Promise.all. В примере формируется массив чисел, из которых создаются промисы, каждый из которых завершается через задержку, зависящую от индекса. Ваша задача – реализовать promiseAll, принимающую массив промисов и возвращающую новый промис, который выполнится, когда все переданные промисы успешно завершатся, либо отклонится при первой ошибке.
const test: number[] = Array.from(Array(5), (_, index) => index);
const promises = test.map((item, index) => {
return new Promise((resolve, reject) => setTimeout(() => resolve(index), index * 100));
});
// promises.push(new Promise((resolve, reject) => reject('MyError')));
const promiseAll = () => {
};
// promiseAll(promises).then(data => console.log(data));
Ответ
Верните Promise, сохраните результаты по исходным индексам и считайте завершения. Первая ошибка отклоняет итоговый Promise; для пустого массива результат — [].
function promiseAll(promises) {
return new Promise((resolve, reject) => {
const items = Array.from(promises);
if (!items.length) return resolve([]);
const results = new Array(items.length);
let remaining = items.length;
items.forEach((item, index) => {
Promise.resolve(item).then(value => {
results[index] = value;
if (--remaining === 0) resolve(results);
}, reject);
});
});
}
Пример вернёт [0, 1, 2, 3, 4] независимо от порядка завершения. Promise.resolve принимает также обычные значения и thenable. Отклонение итогового Promise не отменяет уже запущенные операции. Это учебная реализация, не полная спецификация подклассов Promise.