Нужны состояние pending/fulfilled/rejected, сохранённое значение и список подписчиков. then должен возвращать новый Deferred, а callbacks — выполняться асинхронно.
Самописный аналог Promise на основе класса Deferred
Нужны состояние 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 нельзя.