Ограничение параллелизма удобно реализовать несколькими workers, которые по очереди забирают задачи; loop завершается, когда завершились все workers.
Реализуйте асинхронную очередь задач с ограничением параллелизма: задачи сначала добавляются в очередь, затем запускаются методом loop; одновременно должно выполняться не более заданного числа задач. Когда все задачи из очереди и выполняющиеся задачи завершены, нужно сообщить о завершении очереди.
Ограничение параллелизма удобно реализовать несколькими workers, которые по очереди забирают задачи; loop завершается, когда завершились все workers.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Ограничение параллелизма удобно реализовать несколькими workers, которые по очереди забирают задачи; loop завершается, когда завершились все workers.
Ниже задачи добавляются только до старта, ошибки сохраняются как результаты и не останавливают оставшуюся очередь.
class TaskQueue {
constructor(limit) {
if (!Number.isInteger(limit) || limit < 1) throw new RangeError('limit');
this.limit = limit; this.tasks = []; this.started = false;
}
add(task) {
if (this.started) throw new Error('Queue already started');
if (typeof task !== 'function') throw new TypeError('task');
this.tasks.push(task);
}
async loop() {
if (this.started) throw new Error('Queue already started');
this.started = true;
let next = 0;
const results = new Array(this.tasks.length);
const worker = async () => {
while (next < this.tasks.length) {
const index = next++;
try {
results[index] = {status: 'fulfilled', value: await this.tasks[index]()};
} catch (reason) {
results[index] = {status: 'rejected', reason};
}
}
};
await Promise.all(Array.from({length: Math.min(this.limit, this.tasks.length)}, worker));
return results;
}
}
await queue.loop() служит сигналом завершения, включая пустую очередь.