Самописный аналог Promise на основе класса Deferred

Нужны состояние pending/fulfilled/rejected, сохранённое значение и список подписчиков. then должен возвращать новый Deferred, а callbacks — выполняться асинхронно.

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

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

Нужны состояние pending/fulfilled/rejected, сохранённое значение и список подписчиков. then должен возвращать новый Deferred, а callbacks — выполняться асинхронно.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо создать класс Deferred, который будет воспроизводить основные возможности стандартного Promise. Класс должен принимать функцию‑исполнитель, предоставлять методы then и поддерживать цепочку вызовов. Пример использования выглядит так:

class Deferred {}

const myDeferred = new Deferred((resolve) => {
    setTimeout(() => {
        resolve();
    }, 1000);
})
.then(() => {
    console.log("======");
})
.then(() => {
    console.log("last");
});

Ваша задача – реализовать внутреннюю логику класса так, чтобы пример работал корректно и выводил сообщения в нужном порядке.

Ответ

Нужны состояние pending/fulfilled/rejected, сохранённое значение и список подписчиков. then должен возвращать новый Deferred, а callbacks — выполняться асинхронно.

class Deferred {
  state = 0; value; listeners = [];
  constructor(executor) {
    const settle = (state, value) => {
      if (this.state) return;
      this.state = state; this.value = value;
      for (const run of this.listeners) run();
      this.listeners = [];
    };
    try { executor(value => settle(1, value), error => settle(2, error)); }
    catch (error) { settle(2, error); }
  }
  then(onValue, onError) {
    return new Deferred((resolve, reject) => {
      const run = () => queueMicrotask(() => {
        const handler = this.state === 1 ? onValue : onError;
        if (typeof handler !== 'function') {
          (this.state === 1 ? resolve : reject)(this.value); return;
        }
        try { resolve(handler(this.value)); }
        catch (error) { reject(error); }
      });
      if (this.state) run(); else this.listeners.push(run);
    });
  }
}

Пример напечатает ======, затем last после завершения таймера. Это ограниченная учебная версия для обычных возвращаемых значений: она не усваивает Promise/thenable, не проверяет циклы и не реализует весь Promise/A+. Для полноценной совместимости нужен отдельный алгоритм resolution; подменять ею стандартный Promise нельзя.

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

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

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

Подробнее