Храните хвост Promise-цепочки: add присоединяет задачу к нему и возвращает её результат. После ошибки восстановите внутренний хвост, чтобы очередь продолжила работу.
Создание очереди AsyncQueue для гарантированного последовательного выполнения асинхронных функций
Храните хвост Promise-цепочки: add присоединяет задачу к нему и возвращает её результат. После ошибки восстановите внутренний хвост, чтобы очередь продолжила работу.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо разработать класс, который будет выполнять переданные функции строго одна за другой, даже если они возвращают Promise.
const asyncQueue = new AsyncQueue();
asyncQueue.add(() => console.log("1"));
asyncQueue.add(
() =>
new Promise((resolve) => {
setTimeout(() => {
console.log("2");
resolve();
}, 1000);
})
);
asyncQueue.add(() => console.log("3"));
asyncQueue.add(
() =>
new Promise((resolve) => {
setTimeout(() => {
console.log("4");
resolve();
}, 500);
})
);
Ответ
Храните хвост Promise-цепочки: add присоединяет задачу к нему и возвращает её результат. После ошибки восстановите внутренний хвост, чтобы очередь продолжила работу.
class AsyncQueue {
constructor() { this.tail = Promise.resolve(); }
add(task) {
const result = this.tail.then(() => task());
this.tail = result.then(() => undefined, () => undefined);
return result;
}
}
Пример напечатает 1, 2, 3, 4 независимо от длительности отдельных задач. Вызывающий код обрабатывает ошибку returned Promise. Если задача никогда не завершится, следующие будут ждать; таймаут и отмена требуют отдельного контракта.