Делаем промис - шаг 3
Продолжаем писать собственную реализацию промиса.
В этом шаге разберём, что происходит, если колбэк, переданный в then, возвращает промис.
Сейчас блок then выглядит так:
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
const handleFulfilled = () => {
if (typeof onFulfilled !== "function") {
resolve(this.value);
return;
}
try {
const result = onFulfilled(this.value);
if (result instanceof MyPromise) {
// что делать в этом случае?
} else {
resolve(result);
}
} catch (e) {
reject(e);
}
}
if (this.state === "fulfilled") {
runAsync(handleFulfilled);
}
if (this.state === "pending") {
this.thenHandlers.push(handleFulfilled);
}
if (this.state === "rejected") {
// напишем позже, когда напишем обработчик для колбэка onRejected
}
if (onRejected) {}
});
}
Напомним, кто есть кто здесь:
this- предыдущий промис в цепочкеonFulfilled- колбэк пользователя этого thenresult- то, что вернул onFulfilledresolve/reject- функции, которые меняют состояние нового промиса
Когда result - промис
Представим цепочку:
getUser()
.then(user => getOrders(user.id)) // возвращается промис
.then(orders => console.log(orders));
Здесь важно, чтобы:
- второй
thenдождался завершения вызоваgetOrders(...); - получил не сам промис, а его результат - список заказов;
- если
getOrdersзавершится ошибкой, эта ошибка корректно ушла дальше по цепочке.
Что это означает для реализации?
В случае, если result вернул промис, то обрабатываем это так:
result.then(resolve, reject);
- когда result выполнится - вызвать
resolve(value)для нового промиса - когда result завершится с ошибкой - вызвать
reject(reason).
Так мы и передаём состояние между промисами.
В следующей части реализуем onRejected.