Создайте общий Promise, назначайте каждому входному элементу индекс и уменьшайте счётчик при успехе. Первый reject отклоняет результат, не отменяя остальные операции.
Самостоятельная реализация функции Promise.all
Создайте общий Promise, назначайте каждому входному элементу индекс и уменьшайте счётчик при успехе. Первый reject отклоняет результат, не отменяя остальные операции.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Разработайте собственную версию метода Promise.all, который принимает массив (или любой итерируемый объект) промисов и возвращает новый промис. Результирующий промис должен выполниться успешно, когда все переданные промисы успешно завершатся, и вернуть массив их результатов в порядке соответствия исходному набору. Если хотя бы один из промисов завершится с ошибкой, результирующий промис должен отклониться с этой ошибкой сразу после её появления. При реализации не используйте встроенный Promise.all, а опирайтесь лишь на базовый конструктор Promise и методы then/catch.
Ответ
Создайте общий Promise, назначайте каждому входному элементу индекс и уменьшайте счётчик при успехе. Первый reject отклоняет результат, не отменяя остальные операции.
function promiseAll(iterable) {
return new Promise((resolve, reject) => {
const result = [];
let remaining = 1, index = 0;
for (const value of iterable) {
const current = index++;
remaining++;
Promise.resolve(value).then(item => {
result[current] = item;
if (--remaining === 0) resolve(result);
}, reject);
}
if (--remaining === 0) resolve(result);
});
}
Начальная единица позволяет корректно обработать пустой iterable. Ошибка синхронного итератора отклонит Promise через executor. Это обычный Promise-аналог, без поддержки видового конструктора подклассов встроенного метода.