手写实现Promise,助你透彻理解Promise

//声明一个构造类
class PromiseSelf{
    //记录当前任务状态
    static PENDING="pending"
    static FULFILLED='fulfilled'
    static REJECTED='rejected'
    //new的时候要传递一个函数包含两个参数分别用于调用成功和失败回调
    constructor(executor){
        //对象产生以后赋默认值
        this.value=null;
        this.status=PromiseSelf.PENDING;
        //用于处理主线程产生宏任务以后 解决宏任务执行回调
        this.callbacks=[];
        //解决运行异常抛出机制
        try {
            //构造是便会执行传过来的函数  CLASS默认为严格模式 我们在调用时会发现
            //函数中this指向为undefined  因为我们是直接调用 本身应该指向window
            //使用严格模式禁止提升  变成了undefined  这时需要我们手动绑定this
            executor(this.resolve.bind(this),this.reject.bind(this))
        } catch (error) {
            //当运行出现异常调用失败函数
            this.reject(error);
        }
    }

    resolve(value){
        //根据Promise运行机制可以得知  当状态已经改变时
        //将不会再次改变状态  所以当已经调用过改变状态的函数时
        //让其他改变状态的函数失效
        
        //if用来过滤已经更改过状态的操作
       if(this.status==PromiseSelf.PENDING){
        
        this.value=value;
        this.status=PromiseSelf.FULFILLED;

        //当new Promise时没有执行改变状态的操作  callbacks才会有值 then函数会将回调函数存入callbacks数组中
        //等待状态改变后 来执行回调
        setTimeout(() => {
        
            //如果promise执行时遇到了 改变当前promise状态的宏任务 这个回调必须晚于其执行体内同步操作
            //类似如下情景 必须先输出1 然后执行输出回调的内容
            // setTimeout(()=>{
            //     resolve();
            //     console.log("1");
            // },0)
            this.callbacks.map(callback=>{
                callback.onFULFILLED(value)
            }, 0);
        })
       }
        
    }
    reject(value){
        if(this.status==PromiseSelf.PENDING){
        this.value=value;
        this.status=PromiseSelf.REJECTED;
        setTimeout(() => {
        this.callbacks.map(callback=>{
            callback.onREJECTED(value)
           }, 0);
        })
 
        }
    }
    //想要实现链式调用 then返回的一定是一个新的promise
    then(onFULFILLED,onREJECTED){
        //如果传过来的不是函数 我们给他转换成一个函数
        if(typeof onFULFILLED != 'function'){
            //因为then在没有处理的时候会有穿透效果 
            //这个时候我们要将数据传出去
            onFULFILLED=(value)=>{ return value}
        }
        if(typeof onREJECTED != 'function'){
            onFULFILLED=(value)=>{ return value}
        }
       
       //返回一个promise 使其能链式调用
        return new PromiseSelf((resolve,reject)=>{            
            //注意这里是箭头函数  this指向的是外面的对象
            //而我们构造传过来的(resolve,reject)是已经使用bind强制绑定过this的 
            //所以这两个方法指向的才是我们正在构造的promise
            if (this.status==PromiseSelf.PENDING) {
                this.callbacks.push({
                    onFULFILLED:value=>{
                        try {
                            //保存之前返回的数据 在调用我们新构造的promise的改变状态的方法 
                            
                            let  result =  onFULFILLED(value);
                            //判断返回的是普通数据还是一个promise进行分别处理
                            if(result instanceof PromiseSelf){
                                result.then(res=>{
                                    //用上一个promise返回的promise的状态来改变我们当前new的promise的状态
                                    //我说的可能有点绕口 
                                    resolve(res)
                                },err=>{
                                    reject(err)
                                })
                            }else{
                                resolve(result)
                            }
                        } catch (error) {
                            reject(error)
                        }
                    },
                    onREJECTED:(value)=>{
                        try {
                            let  result=onREJECTED(value)                              
                            if(result instanceof PromiseSelf){
                                result.then(res=>{
                                    resolve(res)
                                },err=>{
                                    reject(err)
                                })
                            }else{
                                resolve(result)
                            }
                        } catch (error) {
                            reject(error)
                        }
                    }
                });
            }
            if(this.status==PromiseSelf.FULFILLED){
                
                setTimeout(() => {
                    try {
                        let  result= onFULFILLED(this.value);
                        
                        if(result instanceof PromiseSelf){
                            result.then(res=>{
                                resolve(res)
                            },err=>{
                                reject(err)
                            })
                        }else{
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    } 
                }, 0);
            }
            if(this.status==PromiseSelf.REJECTED){
                setTimeout(() => {
                    try {
                        let  result= onREJECTED(this.value);
                        if(result instanceof PromiseSelf){
                            result.then(res=>{
                                resolve(res)
                            },err=>{
                                reject(err)
                            })
                        }else{
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                }, 0);
            }
            
        })

        
    }
}
//注意使用then的时候成功回调和错误回调都必须写上 可以只是个空函数 但必须有
//不足之处还望谅解 后续改进
let bb=new PromiseSelf((resolve,reject)=>{ 
    resolve("as")
}).then(res=>{
    console.log(res);
    return new PromiseSelf(res=>{
        res("assdasdasd")
    })
},err=>{}).then(res=>{
    console.log(res);
},err=>{})
console.log(bb);
posted @ 2020-09-21 16:56  门市  阅读(266)  评论(0)    收藏  举报