Promise principle analysis and source code implementation

This code is not well written

Please click here to see better Promise implementation code

Castrated promise

Castration:
When using new to create a promise object and the parameter of resolve is a promise object, the authentic promise should be like this:

let p1 = new Promise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve(123)
    }, 1000);
})
let p2 = new Promise((resolve, reject) => {
    
    
    resolve(p1)
})
p2.then(value => {
    
    console.log(value)})
// 输出 123

And my promise is like this:

let p1 = new MyPromise((resolve, reject) => {
    
    
    setTimeout(() => {
    
    
        resolve(123)
    }, 1000);
})
let p2 = new MyPromise((resolve, reject) => {
    
    
    resolve(p1)
})
p2.then(value => {
    
    console.log(value)})
/* 输出 MyPromise {
  State: 'pending',
  result: null,
  resolveCallBackFuntions: [],
  rejectCallBackFuntions: []
} */

You can see the difference between the two: the authentic Promise will use the result value of p1 as the result value of p2, while my MyPromise will directly use the object of p1 as the result value of p2.
I thought about it and couldn't figure out how to implement this function.

Implementation of MyPromise

Promise is actually a process of changing from asynchronous to synchronous. For an asynchronous task A and a task B, the basic and most important function to be realized by promise is to let A complete the execution, pass the execution result to B, and then B starts again. implement.
Implementation method: Declare a resolve function, and the content of the resolve function is to execute the B task. Pass the resolve function as a parameter so that asynchronous task A can access the resolve function, and then call the resolve function when A task ends, and use the result of A's operation as a parameter. In this way, the most basic and important function above is realized.

MyPromise source code:

In the constructor, the general process is as follows:
there are two arrays inside the object, which store the callbacks to be executed.
When resolve or rejected is executed, the array will be traversed and all callbacks will be executed.

In the then method, the general process is as follows:
add two parameters to the callback array.

Not finished yet. . .

MyPromise():

module.exports = MyPromise
function MyPromise(executor){
    
    
    this.State = 'pending'
    this.result = null
    this.resolveCallBackFuntions = []   //成功时要调用的回调
    this.rejectCallBackFuntions = []    //失败时要调用的回调
    const self = this //让self指向当前promise对象
    function resolve(data){
    
    
        //因为resolve不是通过promise对象来调用的,所以不能在函数内写this,需要用self来代替this
        if (self.State === 'pending') {
    
    
            self.State = 'fullfilled'
            self.result = data
            self.resolveCallBackFuntions.forEach(resolveCallBack => {
    
    
                resolveCallBack.ret(resolveCallBack(self.result)) 
                //resolveCallBack :value => {}回调,并得到返回值,
                //返回值作为ret的参数
            })
        }
        
    }
    function reject(data){
    
    
        if (self.State === 'pending') {
    
    
            self.State = 'rejected'
            self.result = data
            self.rejectCallBackFuntions.forEach(rejectCallBack => {
    
    
                rejectCallBack.ret(rejectCallBack(self.result))
            })
        }
    }
    try{
    
    
        executor(resolve, reject) //在对象生成时就立即执行excutor函数
        //executor的函数体由使用promise的人决定,传入的参数resolve和reject由Promise内部决定
    }
    catch(e){
    
    
        //捕捉throw出来的错误
        reject(e)
    }
}

MyPromise.prototype.then()

MyPromise.prototype.then = function(resolveCallBack, rejectCallBack){
    
    
    if(typeof resolveCallBack !== 'function' && typeof rejectCallBack !== 'function'){
    
    
        return this
    }
    const self = this 
    return new MyPromise((resolve, reject) => {
    
    
        if(typeof resolveCallBack === 'function'){
    
    
            if(self.State === 'fullfilled'){
    
    
                //如果原对象状态是fullfilled,那么立即执行resolveCallback,同步得到返回值,并把返回值作为参数调用ret
                ret(resolveCallBack(self.result))
            }
            else {
    
    
                resolveCallBack.ret = ret
                //这里的this指向new Promise(),所以必须用self来指向调用then的那个对象
                self.resolveCallBackFuntions.push(resolveCallBack)
                //then返回的promise对象结果值是resolveCallBack:value => { }的返回值,同时也将作为resolve的参数
                //现在的目的就是得到resolveCallBack运行后的返回值 当作resolve的参数,
                //但resolveCallBack不是立即执行的,它和调用then方法的promise对象中的resolve一起执行
                //所以我把这个ret和resolveCallBack一同传到上面的promise对象中的resolve里面
                //上面的promise对象中的resolve里面调用ret,ret调用resolve或reject
            }
        }
        if(typeof rejectCallBack === 'function'){
    
    
            if(self.State === 'rejected'){
    
    
                reject(rejectCallBack(self.result))
            }
            else {
    
    
                rejectCallBack.ret = ret
                self.rejectCallBackFuntions.push(rejectCallBack)
            }
            
        }
        function ret(retValue){
    
     
            //ret功能是处理返回值可能为MyPromise对象的情况
            //retValue是resolveCallBack或者rejectCallBack的return值
            //retValue作为then返回对象的结果值
            if(retValue instanceof MyPromise){
    
    
                
                retValue.then(  
                    //如果retvalue是MyPromise对象,那么把retValue的结果值作为then返回对象的结果值
                    //只能把retvalue脱掉一层
                    //如果retvalue的结果值还是MyPromise对象,那么寄,then返回的对象的结果值就只能是个promise了
                    value => {
    
    resolve(value)},  
                    reason => {
    
    reject(reason)}
                    //把retValue的结果值作为then返回的MyPromise的结果值
                )
            }
            else {
    
    
                resolve(retValue)
                //如果不是MyPromise对象,那就直接resolve了
            }
        }
    })
}

MyPromise.prototype.catch()

MyPromise.prototype.catch = function(rejectCallBack){
    
     
    //注意,只要是用到this的函数都不要写成箭头形式,否则this不会指向调用它的对象
    return this.then(undefined, rejectCallBack)
}

MyPromise.resolve()

MyPromise.resolve = x => {
    
    
    return new MyPromise((resolve, reject) => {
    
    
        if(x instanceof MyPromise){
    
    
            x.then(
                value => {
    
    resolve(value)}, 
                reason => {
    
    reject(reason)}
            )
        }
        else {
    
    
            resolve(x)
        }
    })
}

MyPromise.reject()

MyPromise.reject = x => {
    
    
    return new MyPromise((resolve, reject) => {
    
    
        reject(x)
    })
}

MyPromise.all()

MyPromise.all = function(myPromises){
    
    
    return new MyPromise((resolve, reject) => {
    
    
        let resultArr = []
        let resolveCnt = 0
        myPromises.forEach(myPromise => {
    
    
            myPromise.then(
                value => {
    
    
                    resolveCnt++
                    resultArr.push(value)
                    if(resolveCnt === myPromises.length){
    
    
                        resolve(resultArr)
                    }
                },
                reason =>{
    
    
                    reject(reason)
                }
            )
        })
    })
}

MyPromise.race()

MyPromise.race = function(myPromises){
    
    
    return new MyPromise((resolve, reject) => {
    
    
        myPromises.forEach(myPromise => {
    
    
            myPromise.then(
                value => {
    
    
                    resolve(value)
                },
                reason => {
    
    
                    reject(reason)
                }
            )
        })
    })
}

Guess you like

Origin blog.csdn.net/m0_52744273/article/details/124117012