手写简化版promise

89 阅读1分钟

以下代码是简版promise,只能then一次

class Promise2{
    #status = 'peding'
    constructor(fn){
        this.#status = 'pending'
        this.q = []
        const resolve = (data)=>{
            this.#status = 'fulfilled'
            const f1f2 = this.q.shift()
            if(!f1f2 || f1f2[0]) return
            const x = f1f2[0].call(undefined,data)
            if(x instanceof Promise2){
                x.then(()=>{
                    //调用下一个f1
                    resolve(data)
                },()=>{
                    reject(reason)
                })
            }else{
                resolve(x)
                const f1f2 = this.q.shift()
                const x = f1f2[1].call(undefined,data)
            }
        }
        const reject = (reason) =>{
            this.#status = 'rejected'
            const f1f2 = this.q.shift()
            if(!f1f2 || f1f2[1]) return
            const x = f1f2[1].call(undefined,reason)
            if(x instanceof Promise2){
                x.then((data)=>{
                    resolve(data)
                },(reason)=>{
                    reject(reason)
                }else{
                    resolve(x)
                }
            }
        }
        fn.call(undefined,resolve,reject)
    }
    then(f1,f2){
        this.q.push([f1,f2])
        return new Promise 
    }

}

使用promise的小陷阱

const p = Promise.reject(1)
    .then(function f1(){console.log('f1')}, function f2(){console.log('f2')})
    .then(fucntion f3(){console.log('f3')}, function f4(){console.log('f4')})

以上代码打印的是

f2 
f3

why? 因为第二个then所对应的promise不是p而是第一个then所返回的promise,默认是成功的, 这其实类似于责任制,第一个then代表的是第一个责任人,第一个责任人即使收到错误(reject)但是把他解决了,第二个责任人(第二个then)收到的就是成功的,如果为解决,则需要第一责任人返回失败(reject)给第二责任人到reject中处理。

Promise.reject(1) .then(function f1(){console.log('f1')}, function f2(){console.log('f2')}) 所以,若要打印出

f2
f4

则需要

const p = Promise.reject(1)
    .then(function f1(){console.log('f1')}, function f2(){console.log('f2'); return Promise.rejcet(1)})
    .then(fucntion f3(){console.log('f3')}, function f4(){console.log('f4')})