Создание очереди AsyncQueue для гарантированного последовательного выполнения асинхронных функций

Храните хвост Promise-цепочки: add присоединяет задачу к нему и возвращает её результат. После ошибки восстановите внутренний хвост, чтобы очередь продолжила работу.

Короткий ответ

Что ответить на собеседовании

Храните хвост 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. Если задача никогда не завершится, следующие будут ждать; таймаут и отмена требуют отдельного контракта.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее