Запустите N асинхронных работников, которые берут следующий индекс из общей очереди. Результат записывайте по исходному индексу, а не по порядку завершения.
Есть массив из 200 id.
Запустите N асинхронных работников, которые берут следующий индекс из общей очереди. Результат записывайте по исходному индексу, а не по порядку завершения.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Есть массив из 200 id.
Надо для каждого сходить на /api/users/:id. Напиши функцию, которая выполняет запросы, но не больше N одновременно, и возвращает результаты в порядке входного массива.
Ответ
Запустите N асинхронных работников, которые берут следующий индекс из общей очереди. Результат записывайте по исходному индексу, а не по порядку завершения.
async function loadUsers(ids, n) {
if (!Number.isInteger(n) || n < 1) throw new RangeError('n >= 1');
const results = new Array(ids.length);
let next = 0;
let failed = false;
async function worker() {
while (!failed) {
const index = next++;
if (index >= ids.length) return;
try {
const response = await fetch('/api/users/' + encodeURIComponent(ids[index]));
if (!response.ok) throw new Error('HTTP ' + response.status);
results[index] = await response.json();
} catch (error) {
failed = true;
throw error;
}
}
}
await Promise.all(Array.from({ length: Math.min(n, ids.length) }, worker));
return results;
}
При первой ошибке общий Promise отклоняется, новые задания не запускаются; уже начатые запросы не отменяются. Для полной отмены нужен общий AbortController. Память результатов O(m), одновременно выполняется не более N запросов.