promise源码实现,then catch,finally,all,race

发布于:2024-05-19 ⋅ 阅读:(161) ⋅ 点赞:(0)

promise 源码实现

代码

class MyPromise {
    status = 'PENDING';
    result = null;
    reason = null;
    onFulfilledCallbacks = [];
    onRejectedCallbacks = [];
    constructor(execute){
        this.status = 'PENDING';
        let resolve = (result) =>{
            setTimeout(()=>{
                if(this.status === 'PENDING'){
                    this.status = 'FULFILLED';
                    this.result = result
                    this.onFulfilledCallbacks.forEach((callback)=>callback())
                }
            })
    
        }
        let reject = (reason) => {
            setTimeout(()=>{
                if(this.status === 'PENDING'){
                    this.status = 'REJECTED';
                    this.reason = reason;
                    this.onRejectedCallbacks.forEach((callback)=>callback())
                }
            })
        }
       try{
            execute(resolve,reject);
       }catch(e){
        reject(e);
       }
    }
    

    then(onFULFILLED,onREJECTED){
        onFULFILLED = typeof onFULFILLED === 'function'?onFULFILLED:value => value,
        onREJECTED = typeof onREJECTED === 'function' ? onREJECTED : err => { throw err}
        
        let p2 = new MyPromise((resolve,reject)=>{
            let x = null;
            if(this.status === 'FULFILLED'){
                setTimeout(()=>{
                    try{
                        x = onFULFILLED(this.result);
                        resolvePromise(p2,x,resolve,reject)
                    }catch(e){
                        reject(e);
                    }
                })
            }
            if(this.status === 'REJECTED'){
                setTimeout(() => {
                    try{
                        x = onREJECTED(this.reason);
                        reject(x)
                    }catch(e){
                        reject(e);
                    }
                    
                });
            }
            if(this.status === 'PENDING'){
                this.onFulfilledCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            x = onFULFILLED(this.result)
                            resolvePromise(p2,x,resolve,reject)
                        }catch(e){
                            reject(e)
                        }
                    })
                });
                this.onRejectedCallbacks.push(()=>{
                    setTimeout(()=>{
                        try{
                            x = onREJECTED(this.reason);
                            reject(x)
                        }catch(e){
                            reject(e)
                        }
                    })
                });
            }
        })
        return p2;
    }

    catch(onREJECTED){
        return this.then(null,onREJECTED);
    }

    finally(onFinally){
        return this.then((value)=>{
            return MyPromise.resolve(onFinally()).then(()=>value)
        },(error)=>{
            return MyPromise.resolve(onFinally()).then(()=>{throw error})
        })
    }

    static resolve = (value)=>{
        return new MyPromise((resolve,reject)=>{
            resolve(value)
        })
    }

    static reject = (value)=>{
        return new MyPromise((resolve,reject)=>{
            reject(value);
        })
    }

    // 先完成的先执行
    static race = (promises)=>{
        return new MyPromise((resolve,reject)=>{
            for(let i = 0; i < promises.length;i ++){
                //进入resolve 的状态后就不可逆转了。
                promises[i].then(resolve,reject)
            }
        })
    }

    static all = (promises)=>{
        return new MyPromise((resolve,reject)=>{
            const values = new Array(promises.length);
            for(let i = 0; i < promises.length; i ++){
                promises[i].then((value)=>{
                    values[i] = value;
                    if(i === promises.length - 1){
                        resolve(values);
                    }
                },(err)=>{
                    reject(err)
                })
            }
            
        })
    }
}

resolvePromise

//这里可以理解是进行递归,只有普通值才直接返回
function resolvePromise(p2,x,resolve,reject){
    if(p2 === x) return reject(new TypeError('Chaining cycle detected for promise'));
    let called;
    if(x != null && (typeof x === 'object' || typeof x === 'function')){
        try{
            //thenable
            let then = x.then;
            if(typeof then === 'function'){
                then.call(x,(y)=>{
                    if(called) return;
                    called = true;
                    resolvePromise(p2,y,resolve,reject)
                },(err)=>{
                    if(called) return;
                    called = true;
                    reject(err);
                })
            } else{
                resolve(x);
            }
        }catch(err){
            if(called) return;
            called = true;
            reject(err);
        }
    }else{
        resolve(x);
    }
}

参考文章

史上最详细的promise文章
Promise | catch、finally 方法实现(代码版)


网站公告

今日签到

点亮在社区的每一天
去签到