Promise相关方法以及原理,手动实现promise相关功能方法

Promise相关方法以及原理,手动实现promise相关功能方法

在前端面试中Promise被问到的概率非常大,在我面试的过程中,懂技术的基本都会问相关问题。对于初学者来说并没有将Promise吃透,因此在面试中很容易被问到,同时能够手动实现一个Promise也是进入大厂的基础条件,以下是我对promise做的一些整理,欢迎各位大佬进行补充!

promise是一个构造函数,可以把他看作一个容器,里面可以存放异步代码,可以通过then方法来对结果进行处理,promise本身是一个同步任务,其then方法是一个异步任务。通过resolve,reject将成功或者失败的结构返回出去,解决了回调地狱的问题。那我们来手动实现一个promise对象

 //创建Promise构造函数
        function Promise(executor){
            //目前还没有状态,需要先定义
            this.PromiseState="pending";
            this.PromiseResult=null;//定义返回的结果;
            // this.callback={}保存then中的回调,多个回调会覆盖掉里面的方法,因此换成数组进行保存;
            this.callback=[];
            const that=this;//由于resolve,reject中无法拿到this(指向全局),但是需要修改其身上的属性,因此采用浅拷贝进行赋值;
            
            //传入的实参resolve,reject是一个函数,在当前作用域并没有定义,一次需要事先定义
            function resolve(value){
                //resolve改变promise的状态,且状态只能改变一次
                if(that.PromiseState!=="pending"){
                    return
                }//只有为pending时才能修改
                that.PromiseState="fulfilled"
                //修改结果
                that.PromiseResult=value
                // if(that.callback.onResolved){
                //     that.callback.onResolved(value)
                // }
                setTimeout(()=>{
                    that.callback.forEach(item=>{
                    item.onResolved(value)
                })
                })
            }
            function reject(value){
                if(that.PromiseState!=="pending"){
                    return
                }//只有为pending时才能修改
                that.PromiseState="rejected"
                that.PromiseResult=value
                // if(that.callback.onRejected){
                //     that.callback.onRejected(value)
                // }回调为对象时

                //回调为数组时
                setTimeout(()=>{
                    //变为异步
                    that.callback.forEach(item=>{
                    item.onRejected(value)
                })
                })
            }
            
            //promise接收一个回调,其内部会同步自动调用,传入实参resolve,reject
            // executor(resolve,reject)
            try{
                //throw抛出异常也会将结果抛到reject中,采用的是try,catch的原理;
                executor(resolve,reject)//正常情况走try
            }catch(e){
                //有异常走catch
                //抛出的异常会出现在reject中,因此在此调用reject
                reject(e)
            }
        }

定义then方法、`

//定义then方法
        Promise.prototype.then=function(onResolved,onRejected){
            let that=this
            //如果第一个参数没传
            if(typeof onResolved !=="function"){
                value=>value
            }
            //如果没有传递第二个参数
            if(typeof onRejected !=="function"){
                onRejected=reason=>{
                    console.log(reason,"reason");
                    throw reason
                }
            }
            //我们知道then方法的返回值也是一个promise对象,同时该对象的状态也是需要根据结果来修改
            return new Promise((resolve,reject)=>{
                function public(type){
                //由于以下代码重复出现频率较高,只有调用的方法不一样,因此提取为公共代码
                //处理throw
                try{
                    //下面这个方法就是调用的then方法中的onResolved,会返回得到一个结果
                    let result=type(that.PromiseResult)
                    if(result instanceof Promise){
                //如果时promise对象则调用then方法将结果返回出去,同时修改状态
                result.then((v)=>{
                    resolve(v)
                },(r)=>{
                    reject(r)
                })

               }else{
                   //不是promise对象直接修改状态
                   resolve(result)
               }
            }catch(e){
                resolve(e)
            }
            }
                if(this.PromiseState==="fulfilled"){
                    //变为异步
                    setTimeout(()=>{
                        public(onResolved)
                    })
                //判断的得到的状态
            }else if(this.PromiseState==="rejected"){
                setTimeout(()=>{
                    public(onRejected)
                })
        //         try{
        //             console.log(1);
        //         let result=onRejected(this.PromiseResult)
        //         if(result instanceof Promise){
        //             result.then((v)=>{
        //                 resolve(v)
        //             },r=>{
        //                 reject(r)
        //             })
        //         }else{
        //             reject(result)
        //         }
        //     }catch(e){
        //         reject(e)
        //     }
        }
            //以上都是在同步的基础上进行的,下面处理异步任务
            else if(this.PromiseState==="pending"){
                //当promise中的任务是异步的时候,执行then方法时,promise的状态可能还没有改变
                //当其状态改变的时候再去执行then方法中的回调,但是修改状态的方法中无法调用到then方法中的回调,因此我们可以将then方法的回调保存在实列身上
                
                
                // this.callback={
                //     onResolved,
                //     onRejected
                // }使用对象的方式当指定多个回调时,后面的回调会将前面的回调覆盖掉,因此我们使用数组来进行保存
                this.callback.push({
                    // onResolved,
                    // onRejected
                //当为异步是也需要判断then方法返回的结果是否是一个promise对象,因此就不能将onResolved,onRejected直接保存,需要经过处理
                onResolved:function(){
                    public(onResolved)
                    // try{
                    //     let result=onResolved(that.PromiseResult)
                    // if(result instanceof Promise){
                    //     result.then((v)=>{
                    //         resolve(v)
                    //     },(r)=>{
                    //         reject(r)
                    //     })
                    // }else{
                    //     resolve(v)
                    // }
                    // }catch(e){
                    //     reject(e)
                    // }
                },
                onRejected:function(){
                    public(onRejected)
            //   try{
            //     let result=onRejected(that.PromiseResult)
            //         if(result instanceof Promise){
            //             result.then((v)=>{
            //                 resolve(v)
            //             },(r)=>{
            //                 reject(r)
            //             })
            //         }else{
            //             resolve(v)
            //         }
            //     }catch(e){
            //         reject(e)
            //     }
              }
                })
            }

            })
         
        }

定义catch方法

 //定义catch方法
        Promise.prototype.catch=function(onRejected){
            //返回的也是一个promise对象,因为已经定义了then方法,因此直接调用
            return this.then(undefined,onRejected)
        }

定义resolve方法

 Promise.resolve=function(value){
       //返回的也是promise对象
       return new Promise((resolve,reject)=>{
        if(value instanceof Promise){
                value.then(v=>{
                    resolve(v)
                },r=>{
                    reject(r)
                })
            }else{
                resolve(value)
            }
       })
        }

定义reject方法

 //定义promise.reject方法,返回的永远是一个失败的promise
    Promise.reject=function(err){
        return new Promise((resolve,reject)=>{
            reject(err)
        })
    }```
    **定义all方法**
```js
 //promise.all方法
    Promise.all=function(promises){
        //返回一个promise对象
        return new Promise((resolve,reject)=>{
            let count=0;
            let arr=[];
            for(let i=0;i<promises.length;i++){
                promises[i].then(v=>{
                    //得知对象的状态是成功
                    count++;
                    // arr.push(v) push方法无法和传入的数组方法数据保持一致
                   arr[i]=v;
                    if(count===promises.length){
                        resolve(v)
                    }
                },r=>{
                    reject(r)
                })
            }
        })
    }

定义race方法

 //promise.race方法的定义
    Promise.race=function(promises){
        return new Promise((resolve,reject)=>{
            for(let i=0;i<promises.length;i++){
                promises[i].then(v=>{
                    resolve(v)
                },r=>{
                    reject(r)
                })
            }
        })
    }

all方法和race方法的区别在于,all需要传入的数组中的promise对象全部成功才会返回成功的结果放在数组中,且数组中结果的顺序和原来数组中的顺序一一对应,一旦有一个失败的就会返回第一个失败的结果。而race的结果是最先成功的那个promise返回的结果,该结果不一定是发送请求时数组中的第一个。

//测试
 const p=new Promise((resolve,reject)=>{
            // resolve("ok")
            reject("error")
            // throw "err"
            // setTimeout(()=>{
            //     reject("ok")
            // },2000)
        })
        console.log(p);
       const res= p.then((value)=>{
            // console.log(value);
            return "holle"
        })
        const a=p.catch(e=>{
            console.log(e);
        })
        console.log(res,a);//当then方法中没有设置返回值时result为undefined。
        //用对象保存回调该then方法的回调会覆盖掉上面的回调,因此只会执行下面这个回调,因此需要使用数组来保存回调
        // p.then((value)=>{
        //     alert(value);
        // },(err)=>{
        //     alert(err);
        // })
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值