Цель: понять разницу между
Promise.all()
иPromise.allSettled()
и попрактиковаться в обработке всех исходов промисов.
Promise.all
, ваша функция promiseAllSettled
должна возвращать новый Promise
.Promise.allSettled
никогда не отклоняется. Он ждет завершения всех промисов.results
и счетчик settledCount
.promises
. Для каждого элемента:
Promise.resolve()
для универсальной обработки.then()
добавляйте в results
объект вида { status: 'fulfilled', value: ... }
.catch()
добавляйте в results
объект вида { status: 'rejected', reason: ... }
.then
, и в catch
увеличивайте счетчик settledCount
.settledCount
станет равен длине массива promises
, вызовите resolve()
с массивом results
.const promiseAllSettled = (promises) => {
// Возвращаем новый промис. Он будет разрешен, когда все промисы в `promises` завершатся.
// Важно, что этот промис никогда не будет отклонен, в отличие от Promise.all.
return new Promise((resolve) => {
// Массив для хранения итоговых состояний всех промисов.
const results = [];
// Счетчик для отслеживания количества завершенных (settled) промисов.
let settledCount = 0;
// Общее количество промисов для удобства.
const promisesCount = promises.length;
// Если входной массив пуст, немедленно разрешаем промис с пустым массивом.
if (promisesCount === 0) {
resolve([]);
return;
}
// Перебираем каждый элемент входного массива.
promises.forEach((promise, index) => {
// Оборачиваем каждый элемент в `Promise.resolve()`, чтобы единообразно
// обрабатывать и промисы, и обычные значения.
Promise.resolve(promise)
.then(value => {
// Если промис успешно выполнен (fulfilled),
// сохраняем его результат в виде объекта со статусом 'fulfilled'.
results[index] = { status: 'fulfilled', value };
})
.catch(reason => {
// Если промис отклонен (rejected),
// сохраняем причину отклонения в виде объекта со статусом 'rejected'.
results[index] = { status: 'rejected', reason };
})
.finally(() => {
// Блок `finally` выполняется в любом случае: и после `then`, и после `catch`.
// Это гарантирует, что счетчик увеличится для каждого промиса, независимо от его исхода.
settledCount++;
// Если количество завершенных промисов равно общему количеству,
// значит, все промисы завершились.
if (settledCount === promisesCount) {
// Разрешаем основной промис, возвращая массив с результатами.
resolve(results);
}
});
});
});
};
Анализ решения:
Вам нужно реализовать свою собственную версию встроенного статического метода Promise.allSettled()
.
Метод Promise.allSettled(iterable)
возвращает промис, который выполняется после того, как все данные ему промисы завершены (либо выполнены, либо отклонены). Он возвращает массив объектов, каждый из которых описывает результат каждого промиса.
Для каждого результата есть:
status
(строка). Либо 'fulfilled'
, либо 'rejected'
.'fulfilled'
, то присутствует value
.'rejected'
, то присутствует reason
.const p1 = Promise.resolve(3);
const p2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
promiseAllSettled([p1, p2]).then(results => {
/*
results будет:
[
{ status: 'fulfilled', value: 3 },
{ status: 'rejected', reason: 'foo' }
]
*/
console.log(results);
});
promiseAllSettled
.Promise
.Цель: понять разницу между
Promise.all()
иPromise.allSettled()
и попрактиковаться в обработке всех исходов промисов.
Promise.all
, ваша функция promiseAllSettled
должна возвращать новый Promise
.Promise.allSettled
никогда не отклоняется. Он ждет завершения всех промисов.results
и счетчик settledCount
.promises
. Для каждого элемента:
Promise.resolve()
для универсальной обработки.then()
добавляйте в results
объект вида { status: 'fulfilled', value: ... }
.catch()
добавляйте в results
объект вида { status: 'rejected', reason: ... }
.then
, и в catch
увеличивайте счетчик settledCount
.settledCount
станет равен длине массива promises
, вызовите resolve()
с массивом results
.const promiseAllSettled = (promises) => {
// Возвращаем новый промис. Он будет разрешен, когда все промисы в `promises` завершатся.
// Важно, что этот промис никогда не будет отклонен, в отличие от Promise.all.
return new Promise((resolve) => {
// Массив для хранения итоговых состояний всех промисов.
const results = [];
// Счетчик для отслеживания количества завершенных (settled) промисов.
let settledCount = 0;
// Общее количество промисов для удобства.
const promisesCount = promises.length;
// Если входной массив пуст, немедленно разрешаем промис с пустым массивом.
if (promisesCount === 0) {
resolve([]);
return;
}
// Перебираем каждый элемент входного массива.
promises.forEach((promise, index) => {
// Оборачиваем каждый элемент в `Promise.resolve()`, чтобы единообразно
// обрабатывать и промисы, и обычные значения.
Promise.resolve(promise)
.then(value => {
// Если промис успешно выполнен (fulfilled),
// сохраняем его результат в виде объекта со статусом 'fulfilled'.
results[index] = { status: 'fulfilled', value };
})
.catch(reason => {
// Если промис отклонен (rejected),
// сохраняем причину отклонения в виде объекта со статусом 'rejected'.
results[index] = { status: 'rejected', reason };
})
.finally(() => {
// Блок `finally` выполняется в любом случае: и после `then`, и после `catch`.
// Это гарантирует, что счетчик увеличится для каждого промиса, независимо от его исхода.
settledCount++;
// Если количество завершенных промисов равно общему количеству,
// значит, все промисы завершились.
if (settledCount === promisesCount) {
// Разрешаем основной промис, возвращая массив с результатами.
resolve(results);
}
});
});
});
};
Анализ решения:
Вам нужно реализовать свою собственную версию встроенного статического метода Promise.allSettled()
.
Метод Promise.allSettled(iterable)
возвращает промис, который выполняется после того, как все данные ему промисы завершены (либо выполнены, либо отклонены). Он возвращает массив объектов, каждый из которых описывает результат каждого промиса.
Для каждого результата есть:
status
(строка). Либо 'fulfilled'
, либо 'rejected'
.'fulfilled'
, то присутствует value
.'rejected'
, то присутствует reason
.const p1 = Promise.resolve(3);
const p2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
promiseAllSettled([p1, p2]).then(results => {
/*
results будет:
[
{ status: 'fulfilled', value: 3 },
{ status: 'rejected', reason: 'foo' }
]
*/
console.log(results);
});
promiseAllSettled
.Promise
.Редактор кода намеренно скрыт на мобильном.
Поверь, так лучше: я оберегаю тебя от искушения писать код в неидеальных условиях. Маленький экран и виртуальная клавиатура — не лучшие помощники для программиста.
📖 Сейчас: Изучи задачу, продумай решение. Действуй как стратег.
💻 Потом: Сядь за компьютер, открой сайт и реализуй все идеи с комфортом. Действуй как код-джедай!