Запустите не больше limit работников с общим индексом. Каждый берёт следующую задачу только после завершения предыдущей и записывает результат на исходную позицию.
Параллельный запуск запросов с ограничением количества
Запустите не больше limit работников с общим индексом. Каждый берёт следующую задачу только после завершения предыдущей и записывает результат на исходную позицию.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Создайте функцию, которая для каждого элемента входного массива вызывает переданный callback и собирает результаты в массив ответов Response[].
Выполнение запросов должно происходить одновременно, однако количество одновременно запущенных запросов ограничено параметром limit. Такая схема позволяет уменьшить общее время работы программы, не перегружая ресурсы.
type Props<RequestData, Response> = {
callback: (args: RequestData) => Promise<Response>;
data: Array<RequestData>;
limit: number;
};
/* Решение задачи */
export async function runWithLimit<RequestData, Response>({
callback,
data,
limit,
}: Props<RequestData, Response>): Promise<Response[]> {
/* START SOLUTION HERE */
const result: Response[] = [];
return Promise.all([]);
}
Ответ
Запустите не больше limit работников с общим индексом. Каждый берёт следующую задачу только после завершения предыдущей и записывает результат на исходную позицию.
export async function runWithLimit<RequestData, Response>({ callback, data, limit }: Props<RequestData, Response>): Promise<Response[]> {
if (!Number.isInteger(limit) || limit < 1) throw new RangeError('limit must be positive');
const result: Response[] = new Array(data.length);
let next = 0, failed = false;
async function worker() {
while (!failed) {
const index = next++;
if (index >= data.length) return;
try { result[index] = await callback(data[index]); }
catch (error) { failed = true; throw error; }
}
}
await Promise.all(Array.from({ length: Math.min(limit, data.length) }, () => worker()));
return result;
}
В JavaScript получение индекса выполняется синхронно до await, поэтому работники не берут один элемент дважды. После первой ошибки новые задания не запускаются, но уже выполняющиеся не отменяются автоматически. Пустой вход возвращает [], порядок результатов не зависит от скорости запросов.