Promise 实现
const Pending = 'pending';
const Fulfilled = 'fulfilled';
const Rejected = 'rejected';
//把观察者抽象成方法的观察者模式
class MyPromise {
constructor(executor) {
this.status = Pending;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = value => {
if (this.status !== Pending) return;
this.status = Fulfilled;
this.value = value;
this.onFulfilledCallbacks.forEach(callback => {
callback(value);
});
};
const reject = reason => {
if (this.status !== Pending) return;
this.status = Rejected;
this.reason = reason;
this.onRejectedCallbacks.forEach(callback => {
callback(reason);
});
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
if (this.status === Fulfilled) {
onFulfilled(this.value);
} else if (this.status === Rejected) {
onRejected(this.reason);
} else if (this.status === Pending) {
onFulfilled(this.value);
onRejected(this.reason);
}
}
}
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('success');
}, 1000);
});
p1.then(value => {
console.log('p1 resolved with', value);
});
-
目前没有实现
链式调用
,可以发现Promise
是对观察者模式
的改造 -
订阅者
从对象
抽象成了方法
,通过then
方法订阅更新
-
被观察者
不是Promise
,而是由外部定义,通过回调resolve
reject
来发布更新
链式调用,修改 then
方法
then(onFulfilled, onRejected) {
// 为了方便描述 接下来都用成功情况进行说明
// 链式调用的核心 就是 then 方法返回一个新的 promise实例 下文称nextPromise
// 当前的promise实例称 currentPromise
// resolve 函数被调用时 promise实例 会被 完成
const nextPromise = new MyPromise((resolve, reject) => {
// 如果 异步已经结束 状态已经被修改
// 则 直接完成 nextPromise
// 结果是 currentPromise的结果经过 currentPromise 的 onFulfilled 处理后的返回值
if (this.status === Fulfilled) {
resolve(onFulfilled(this.value));
} else if (this.status === Rejected) {
reject(onRejected(this.reason));
}
// 如果 异步没有结束 状态还是Pending
// 则 会在 currentPromise 订阅更新 也就是插入一个方法 跟原来一样
// 但插入的方法有些改变
// 插入的方法为 完成 nextPromise
// nextPromise的结果 是 currentPromise的结果经过 currentPromise 的 onFulfilled 处理后的返回值
//跟直接完成时一样,只是不立刻执行,而是加入 currentPromise 的 回调队列中,也就是订阅的更新中
else if (this.status === Pending) {
this.onFulfilledCallbacks.push(() => resolve(onFulfilled(this.value)));
this.onRejectedCallbacks.push(() => reject(onRejected(this.reason)));
}
});
return nextPromise;
}
const p1 = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('success');
}, 1000);
});
//p1 是 currentPromise p2 是 nextPromise
const p2 = p1.then(value => {
console.log('p1 resolved with', value);
return 'p2';
});
//p2 是 currentPromise
p2.then(value => {
console.log('p2 resolved with', value);
});
- 链式调用的核心就是对
订阅的更新(方法)
进行封装 - 在运行回调的同时,
完成
新返回的实例
,将回调的返回值
作为新返回的实例
的结果