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