Сохраняйте каждое значение на его исходном индексе и уменьшайте счётчик ожидаемых результатов. При первой ошибке отклоняйте общий Promise с полученной причиной.
Создание собственного Promise.all
Сохраняйте каждое значение на его исходном индексе и уменьшайте счётчик ожидаемых результатов. При первой ошибке отклоняйте общий Promise с полученной причиной.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Реализуйте функцию, имитирующую поведение Promise.all. Функция должна принимать массив объектов‑промисов и возвращать новый промис. Этот промис должен выполнить resolve с массивом значений, полученных от всех переданных промисов, либо выполнить reject сразу же при отказе любого из них, передавая причину первого отказа.
Пример использования:
customAll([p1, p2, p3])
.then(results => console.log(results))
.catch(err => console.error(err));
Ответ
Сохраняйте каждое значение на его исходном индексе и уменьшайте счётчик ожидаемых результатов. При первой ошибке отклоняйте общий Promise с полученной причиной.
function customAll(promises) {
return new Promise((resolve, reject) => {
const items = Array.from(promises);
const values = new Array(items.length);
let remaining = items.length;
if (!remaining) return resolve(values);
items.forEach((item, index) => Promise.resolve(item).then(value => {
values[index] = value;
if (--remaining === 0) resolve(values);
}, reject));
});
}
Пустой набор возвращает выполненный Promise с []. Порядок завершения задач не меняет порядок массива. Promise.resolve также обрабатывает обычные значения. После ошибки уже начавшиеся операции продолжаются, если у них нет отдельного механизма отмены.