简介
通过实现一个PromiseA+来加强对promise的理解,仅供参考~
讲解请看注释
// https://promisesaplus.com/
function onResolvedDefault() {}
function onRejectedDefault() {}
class PromiseA {
status: 'pending' | 'resolved' | 'rejected' = 'pending'// promise的状态
value: any = undefined// resolve的值
reason: any = undefined // reject 的原因
resolveCallbacks: Function[] = [] // 成功时的回调数组
rejectCallbacks: Function[] = [] // 失败时的回调数组
constructor(executor: Function) {
executor(this.resolve.bind(this), this.reject.bind(this))
}
private resolve(value: any) {
if(this.status === 'pending') {
this.value = value
this.status = 'resolved'
this.resolveCallbacks.forEach(fn => {
fn(this.value)
})
}
}
private reject(reason: any) {
if(this.status === 'pending') {
this.reason = reason
this.status = 'rejected'
this.rejectCallbacks.forEach(fn => {
fn(this.reason)
})
}
}
then(onResolved?, onRejected?) {
const that = this
const _onResolved = typeof onResolved === 'function' ? onResolved : onResolvedDefault
const _onRejected = typeof onResolved === 'function' ? onRejected : onRejectedDefault
if (this.status === 'resolved') {
// 2.2.6 then must return a promise
return new PromiseA( /* 记作 resolvePromise*/
// 这里不使用箭头函数时因为, 我们在调用resolvePromise需要this上面这个新生成的resolvePromise实例
function(resolve, reject) {
const res = _onResolved(that.value)
// 2.2.7.1 [[Resolve]](resolvePromise, x)
// 这个this指向这里新返回的 rejectPromise
resolvePromise(this, res, resolve, reject)
}
)
}
if (this.status === 'rejected') {
return new PromiseA(
function(resolve, reject) {
const res = _onRejected(that.reason)
resolvePromise(this, res, resolve, reject)
}
)
}
if (this.status === 'pending') {
return new PromiseA(function(resolve, reject) {
that.resolveCallbacks.push(
function(value) {
const res = _onResolved(value)
resolvePromise(this, res, resolve, reject)
}
)
that.rejectCallbacks.push(
function(reason) {
const res = _onRejected(reason)
resolvePromise(this, res, resolve, reject)
}
)
})
}
}
}
// 这个函数只要结合 https://promisesaplus.com/ 网站上的
// 从 --To run [[Resolve]](promise, x), perform the following steps:-- 开始的解释逐句翻译过来就行了
function resolvePromise(promise: PromiseA, val: any, resolve, reject) {
// val可能的值 普通值(直接可用) | PromiseA的实例 | thenable对象
// 判断 x 是否为对象(排除null情况)或函数
let called = false;
if(promise === val) throw new TypeError() // 2.3.1
// if(val instanceof PromiseA) {
// val.then(resolve, reject)
// }
if ((typeof val === "object" && val !== null) || typeof val === "function") {
if (typeof val.then === "function") {
val.then.call(val,
(value) => {
// 添加锁,避免成功后执行失败
if (called) return;
called = true;
resolvePromise(promise, value, resolve, reject);
},
(reason) => {
// 添加锁,避免失败后执行成功
if (called) return;
called = true;
reject(reason);
}
);
} else {
resolve(val);
}
} else {
resolve(val)
}
}
测试代码
const aa = new PromiseA((resolve, reject) => {
resolve('1111')
}).then(val => {
console.log(val)
return new PromiseA((resolve) => {
setTimeout(() => {
resolve('222')
}, 1000)
})
})
aa.then(console.log)
/// 111
/// 222(一秒后)