简单手写promise

前端面试经常被问promise,查阅资料后就想手写一个简单的promise实现

1.新建一个promise类,考虑到peomise,是由状态推动的,添加状态,结果和错误原因等属性

class newsPomise{
    constructor(executor){
      
      this.status="pending" //执行状态
      this.value = ""//结果
      this.reason = "";//原因
      
      
    }

    
      
    
    
       
 
 
 }

2.在promise中两个函数作为参数分别作为状态为fullfilled--resolve和reject--reject

class newsPomise{
    constructor(executor){
      
      this.status="pending" //执行状态
      this.value = ""//结果
      this.reason = "";//原因
     
    }

    
      
    
    resolve(data){
        
            if(this.status=="pending") {
                this.status=="resolve"
                this.value=data
               
            }
        
        
    }
    reject(reason){
         
            if(this.status=="pending") {
                this.status=="reject"
                this.value=reason
                
            }
        
       
    }
    
 }

3. 在promise函数中是立执行的,添加executor函数作为立执行函数

class newsPomise{
    constructor(executor){      
      this.status="pending" //执行状态
      this.value = ""//结果
      this.reason = "";//原因 
      executor(this.resolve,this.reject)    
    }

这样执行过后会出现报错,指向this为window,所以使用bind来改变this指向

class newsPomise{
    constructor(executor){
      
      this.status="pending" //执行状态
      this.value = ""//结果
      this.reason = "";//原因
      
      
        executor(this.resolve.bind(this),this.reject.bind(this))
     
    }

此处可以基本执行,但多考虑一点直接抛出错误后reject执行不到,这里用到try...catch,进行错误的抓取,ps:catch中的this非window

class newsPomise{
    constructor(executor){
      
      this.status="pending" //执行状态
      this.value = ""//结果
      this.reason = "";//原因
   
      try{
        //立即执行
        executor(this.resolve.bind(this),this.reject.bind(this))
    }catch{
        this.reject(e)
    }
    }

4.现在考虑promise.then(function1,function2)

then(onresolve,onreject){
 //使用条件运算符,如果参数不是函数那么做判断返回一个空函数
     onresolve= typeof onresolve=="function"?onresolve:()=>{}
     onreject= typeof onresolve=="function"?onreject:()=>{}
     if(this.status=="resolve") {
           onresolve(this.value)
         }
     if(this.status=="reject") {
           onreject(this.value)
                 
     }
   }

这样就可以得到then的功能,不过这里并没有体现出异步的能力,我们需要resolve和reject的函数中添加异步操作,且resolve和reject的代码需要在最后执行,所以

 resolve(data){
        setTimeout(()=>{
            if(this.status=="pending") {
                this.status=="resolve"
                this.value=data
                
            }
        })
        
    }
    reject(reason){
        setTimeout(()=>{
            if(this.status=="pending") {
                this.status=="reject"
                this.value=reason
                
            }
        })
       
    }
    then(onresolve,onreject){
        
              //使用条件运算符,如果参数不是函数那么做判断返回一个空函数
           
            onresolve= typeof onresolve=="function"?onresolve:()=>{}
            onreject= typeof onresolve=="function"?onreject:()=>{}
             
            if(this.status=="resolve") {
               //同时考虑异步操作,实际还是用到了定时器
                setTimeout(()=>{
                    onresolve(this.value)
                })
                
                
            }
            if(this.status=="reject") {
                setTimeout(()=>{
                    onreject(this.value)
                })
                
            }
        })
       
 
    }

5.我们在promise中形参函数中resolve用定时器包裹,用then来做成功回调,会执行resolve,但根据我们的代码执行后会发现不会在执行resolve,那是因为根据事件循环,执行promise内部函数后会执行then的成功回调,由于状态还没有变为成功的状态,所以不会执行then中的成功回调,我们需要在then中添加状态为pending时,传进来的回调函数,这里可以用发布--订阅的模式来解决

先在constructor中添加两个属性来存入回调函数
 this.resolveArrs=[];
 this.rejectArrs=[]
在状态成功时进行释放
resolve(data){
        setTimeout(()=>{
            if(this.status=="pending") {
                this.status=="resolve"
                this.value=data
                this.resolveArrs.forEach(item=>[
                    item(data)
                ])
            }
        })
        
    }
    reject(reason){
        setTimeout(()=>{
            if(this.status=="pending") {
                this.status=="reject"
                this.value=reason
                this.rejectArrs.forEach(item=>[
                    item(reason)
                ])
            }
        })
       
    }
在then中状态为pending时添加订阅者
 if(this.status="pending"){//添加观察者
                this.resolveArrs.push(onresolve)
                this.rejectArrs.push(onresolve)
            }

6.然后就是then的链式调用

 then(onresolve,onreject){
        //使用then,返回链式结构promise
         //使用条件运算符,如果参数不是函数那么做判断返回一个空函数
        return new newsPomise((onresolve,onreject)=>{
           
            onresolve= typeof onresolve=="function"?onresolve:()=>{}
            onreject= typeof onresolve=="function"?onreject:()=>{}
            if(this.status="pending"){//添加观察者
                this.resolveArrs.push(onresolve)
                this.rejectArrs.push(onresolve)
            }
         //同时考虑异步操作,实际还是用到了定时器
            if(this.status=="resolve") {
               
                setTimeout(()=>{
                    onresolve(this.value)
                })
                
                
            }
            if(this.status=="reject") {
                setTimeout(()=>{
                    onreject(this.value)
                })
                
            }
        })
       
//         onresolve= typeof onresolve=="function"?onresolve:function(data){this.resolve(data)}
//         onreject= typeof onresolve=="function"?onreject:function(data){this.reject(data)}
    }

完整代码 错误返回this.reject(error)

class newsPomise{
    constructor(executor){
      
      this.status="pending" //执行状态
      this.value = ""//结果
      this.reason = "";//原因
      this.resolveArrs=[];//添加数组的原因,是为了利用发布与观察者模式,在状态为pending状态时添加到数组中作为回调函数来调用
      this.rejectArrs=[]
      try{
        //立即执行
        executor(this.resolve.bind(this),this.reject.bind(this))
    }catch{
        this.reject(e)
    }
    }

    
      
    
    resolve(data){
        setTimeout(()=>{
            if(this.status=="pending") {
                this.status=="resolve"
                this.value=data
                this.resolveArrs.forEach(item=>[
                    item(data)
                ])
            }
        })
        
    }
    reject(reason){
        setTimeout(()=>{
            if(this.status=="pending") {
                this.status=="reject"
                this.value=reason
                this.rejectArrs.forEach(item=>[
                    item(reason)
                ])
            }
        })
       
    }
    then(onresolve,onreject){
        //使用then,返回链式结构promise

        return new newsPomise((onresolve,onreject)=>{
             //使用条件运算符,如果参数不是函数那么做判断返回一个空函数
            onresolve= typeof onresolve=="function"?onresolve:()=>{}
            onreject= typeof onresolve=="function"?onreject:()=>{}
            if(this.status="pending"){//添加观察者
                this.resolveArrs.push(onresolve)
                this.rejectArrs.push(onresolve)
            }
           //同时考虑异步操作,实际还是用到了定时器
            if(this.status=="resolve") {
               
                setTimeout(()=>{
                    onresolve(this.value)
                })
                
                
            }
            if(this.status=="reject") {
                setTimeout(()=>{
                    onreject(this.value)
                })
                
            }
        })
 
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值