const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECT = 'rejected';
class MyPromise {
#state = PENDING
#result = undefined
#handler = []
constructor(executor){
const resolve = (data) => {
this.#changeState(FULFILLED, data)
}
const reject = (err) => {
this.#changeState(REJECT, err)
}
try{
executor(resolve, reject)
}
catch(err){
reject(err)
}
}
#changeState(state, result){
if(this.#state !== PENDING) return
this.#state = state
this.#result = result
this.#run()
}
// 判断这个callback是不是一个promise
#isPromiseLike(value){
return typeof value === 'object' && typeof value.then === 'function'
// return value instanceof MyPromise || value[Symbol.for('nodejs.runtime.asm.promise')] instanceof MyPromise || value[Symbol.for('nodejs.runtime.asm.promise.constructor')] instanceof MyPromise;
}
// 手动将函数添加到微任务
#runMicroTask(fun){
if (typeof MutationObserver !== 'undefined') {
const textNode = document.createTextNode('0')
const ob = new MutationObserver(fun)
ob.observe(textNode, { characterData: true })
textNode.data = '1'
} else {
process.nextTick(fun)
}
}
#runCall(callBack, resolve, reject){
// then中的回调需要放在微队列中
this.#runMicroTask(() => {
// console.log('www',callBack, resolve, reject)
if (typeof callBack === "function") {
try{
const data = callBack(this.#result);
// 判断这个data返回的是不是一个promise
if(this.#isPromiseLike(data)){
data.then(resolve, reject)
} else resolve(data)
}
catch{
reject(this.#result)
}
} else {
const settled = this.#state === FULFILLED ? resolve : reject
settled(this.#result) //链式回调穿透
}
})
}
#run(){
if (this.#state === PENDING) return
while(this.#handler.length){
const {onFulfilled, onRejected, resolve, reject} = this.#handler.shift()
if (this.#state === FULFILLED) {
this.#runCall(onFulfilled, resolve, reject)
} else {
this.#runCall(onRejected, resolve, reject)
}
}
}
then(onFulfilled, onRejected){
return new MyPromise((resolve,reject) => {
this.#handler.push({
onFulfilled,
onRejected,
resolve,
reject
})
this.#run() //recursion to avoid stack overflow.
})
}
//MDN文档解释: 处理失败回调,处理方式与then方式一样
catch(onRejected){
return this.then(undefined, onRejected)
}
//无论成功失败都要执行这个回调
finally(onFinally) {
return this.then(
data => {
onFinally() // MDN文档解释:onFinally他不接受任何参数,因为他不关心成功还是失败
return data
},
(err) => {
onFinally()
throw err
}
)
}
//MDN文档解释:resolve,reject是一个静态方法
static resolve(value){
if (value instanceof MyPromise) return value
let _resolve, _reject;
const p = new MyPromise((resolve, reject) => { //静态方法事无法访问实例方法的 所以const p存
_resolve = resolve;
_reject = reject;
})
if(p.#isPromiseLike(value)){
value.then(_resolve, _reject)
}
else {
_resolve(value)
}
return p
}
static reject(reason){
return new MyPromise((resolve, reject) => {
reject(reason)
})
}
}
、
执行:
const p = new MyPromise((resolve,reject) => {
resolve(1)
}) //constructor for a promise
p.then((val) => {
console.log('data1',val)
return 123
}).then((data) => {
console.log('data2',data)
})
MyPromise.resolve(121212).then((data)=>{
console.log(data)
})
输出:
[Running] node "d:\console\utils\myPromise.js"
data1 1
data2 123
121212