为了加深对Promise的理解,参考网上资源手写了下Promise。还有待通过官方测试用例: github.com/promises-ap…
const PENDING = 'PENDING'; // 进行中
const FULFILLED = 'FULFILLED'; // 已成功
const REJECTED = 'REJECTED'; // 已失败
function isMyThenable(p) {
return ((typeof p === 'object' && p !== null) ||
typeof p === 'function') &&
typeof p.then === 'function'
}
class MyPromise {
constructor(exector) {
this.status = PENDING
this.value = undefined
this.reason = undefined
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
const resolve = (value) => {
if (this.status === PENDING) {
/**
* value 如果是个 thenable 或者 promise 实例,则当前正在执行的这个 resolve 所归属的 promise 的状态
* 跟随 value 的状态
*/
if (isMyThenable(value)) {
/**
* 凡是执行 then 方法的地方都放进任务队列异步处理
*/
setTimeout(() => {
try {
value.then(resolve, reject)
} catch (e) {
reject(e)
}
})
} else {
this.status = FULFILLED
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn(this.value))
}
}
}
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
try {
exector(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
onRejected = typeof onRejected === 'function' ? onRejected:
reason => { throw new Error(reason instanceof Error ? reason.message : reason) }
const self = this
const p2 = new MyPromise((resolve, reject) => {
const processCallbackReturn = (promise, x, resolve, reject) => {
if (x === promise) {
// x 是 promise 实例,抛出异常
return reject(new TypeError())
}
/**
* 如果 x 是一个 promise 实例,p2 则跟随 x 的状态
*/
if (x instanceof MyPromise) {
/**
* 凡是执行 then 方法的地方都放进任务队列异步处理
*/
setTimeout(() => {
x.then((y) => processCallbackReturn(promise, y, resolve, reject), reject)
})
} else if (
typeof x === 'object' ||
typeof x === 'function'
) {
/**
* 如果 x 是一个对象或者函数
*/
let then
// 如果取 x.then 时候抛异常,则 p2 状态为 REJECTED,且 reason 为 e
try {
then = x.then
} catch (e) {
return reject(e)
}
// 如果 then 是一个函数
if (typeof then === 'function') {
let called = false
/**
* 此时 p2 的状态取决于 then 方法中如何调用 resolve 和 reject
* 1. 当 then 内部调用 resolve(y),则重新判断 y 的状态来决定 p2 的状态
* 2. 当 then 内部调用 reject(r),则 p2 的状态为 REJECTED,且 reason 为 r
* 3. 当 then 内部同时调用了 resolve 和 reject,或者比如对同一个 y,执行了多次 resolve(y),
* 则只取第一次执行的 resolve 或者 reject 的结果
* 4. 当 then 内部执行时抛出异常 e:
* 1) 如果 resolve 或者 reject 已经调用过,则忽略该异常
* 2) 否则 p2 的状态为 REJECTED,且 reason 为 e
* */
/**
* 凡是执行 then 方法的地方都放进任务队列异步处理
*/
setTimeout(() => {
try {
then.call(
x,
y => {
if (called) return
called = true
processCallbackReturn(promise, y, resolve, reject)
},
r => {
if (called) return
called = true
reject(r)
},
)
} catch (e) {
if (called) return
reject(e)
}
})
} else {
// 如果 then 不是一个函数,则 p2 的状态为 FULFILLED,且 value 为 x
resolve(x)
}
} else {
// 如果 x 不是对象也不是函数,则 p2 的状态为 FULFILLED,且 value 为 x
resolve(x)
}
}
const resolvePromise = (cb, value) => {
setTimeout(() => {
try {
const x = cb(value)
processCallbackReturn(p2, x, resolve, reject)
} catch (e) {
reject(e)
}
})
}
if (self.status === PENDING) {
self.onFulfilledCallbacks.push(() => {
resolvePromise(onFulfilled, self.value)
})
self.onRejectedCallbacks.push(() => {
resolvePromise(onRejected, self.reason)
})
} else if (self.status === FULFILLED) {
resolvePromise(onFulfilled, self.value)
} else if (self.status === REJECTED) {
resolvePromise(onRejected, self.reason)
}
})
return p2
}
catch(onRejected) {
return this.then(null, onRejected)
}
static resolve(value) {
if (value instanceof MyPromise) {
return value
} else {
return new MyPromise((resolve, reject) => resolve(value))
}
}
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
static all(promiseArr) {
const len = promiseArr.length
const values = new Array(len)
let count = 0
return new MyPromise((resolve, reject) => {
for (let i = 0; i < len; i++) {
MyPromise.resolve(promiseArr[i]).then(
val => {
values[i] = val
count++
if (count === len) resolve(values)
},
err => reject(err)
)
}
})
}
static race(promiseArr) {
return new MyPromise((resolve, reject) => {
promiseArr.forEach(p => {
MyPromise.resolve(p).then(
val => resolve(val),
err => reject(err),
)
})
})
}
}
/**
* test case
*
* out:
*
* 0 1 2 4 3 5 6
*
* 在 node16.16.0 中用 Promise 执行的 结果是
* 0 1 2 3 4 5 6
*/
MyPromise.resolve().then(() => {
console.log(0);
return MyPromise.resolve(4)
}).then(res => {
console.log(res);
})
MyPromise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(2);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
}).then(() => {
console.log(6);
})
/**
* test case
*
* out
*
* 2 1
*/
new MyPromise((resolve, reject) => {
MyPromise.resolve().then(() => {
resolve({
then: (resolve, reject) => resolve(1)
});
MyPromise.resolve().then(() => console.log(2));
});
}).then(v => console.log(v));