简单的Promise实现

117 阅读2分钟

简单的Promise实现

promise自我介绍

君子一诺千金,承诺的事情一定会做到

promise应用场景

解决回调地狱问题

Promise基本用法

 let p=new Promise((resolve,reject)=>{
      // resolve('1')
      // reject('err')
      setTimeout(() => {
        resolve('23')
      }, 1000);
    })
    console.log(p)
    p.then(response=>{
      console.log(response); //23
    },err=>{
      console.log(err);
    })

Promise基本规范

  • Promise是立即执行的
  • Promise有3种状态,pendding、fulfilld、rejected。pendding-->resolved,pendding-->fulfilld,状态不可逆
  • 每一个Promise都有一个then方法
  • 如果new Promise报错了会走失败方法reject()
//第一步基础代码
class MyPromise{
      constructor(executor){
        this.status="pendding"
        this.value=""
        this.reason=""
        try {
          executor(this._resolve.bind(this),this._reject.bind(this))
        } catch (error) {
          this._reject(error)
        }
      }
      _resolve(value){
        if(this.status==='pendding'){
          this.status="resolved"
          this.value=value
        }
      }
      _reject(reason){
        if(this.status==='pendding'){
          this.status='rejected'
          this.reason=reason
        }

      }
      then(onFullFilled,onRejected){
        if(this.status==='resolved'){
          onFullFilled(this.value)
        }
        if(this.status==='rejected'){
          onRejected(this.reason)
        }
      }
    }
    let p1=new MyPromise((resolve,reject)=>{
       resolve('1')
      // reject('err')
    })
    p1.then(response=>{
      console.log(response);
    },err=>{
      console.log(err);
    })

第一步完成,但是当我们碰到异步调用时,状态就会卡在pendding,不会变成resolved。(根据事件循环机制。执行到then方法时,异步代码里的resolve还没调用,状态就还没变)。此时我们使用一个发布订阅模式。在pendding状态时将成功回调函数和失败的回调函数存到他们各自的数组中去,等到resolve或者reject时,再调用他们。

  • 在pendding状态时先收集各回调函数:
 then(onFullFilled,onRejected){
    if(this.status==='resolved'){
      onFullFilled(this.value)
    }
    if(this.status==='rejected'){
      onRejected(this.reason)
    }
    //异步
    if(this.status==='pendding'){

      this.onResolvedCallbacks.push(()=>{onFullFilled(this.value)})
      this.onRejectedCallbacks.push(()=>{onRejected(this.reason)})
    }
  }
  • 当状态变化的时候就执行发布他们:
 _resolve(value){
        if(this.status==='pendding'){
          this.status="resolved"
          this.value=value
          //发布
          this.onResolvedCallbacks.forEach(fn=>{
            console.log('8',fn);
            fn()
          })
        }

      }
      _reject(reason){
        if(this.status==='pendding'){
          this.status='rejected'
          this.reason=reason
           //发布
          this.onRejectedCallbacks.forEach(fn=>{
            fn()
          })
        }

      }

下面是完整代码:

    let p=new Promise((resolve,reject)=>{
      // resolve('1')
      // reject('err')
      setTimeout(() => {
        resolve('23')
      }, 1000);
    })
    console.log(p)
    p.then(response=>{
      console.log(response);
    },err=>{
      console.log(err);
    })
    // 1。立即执行
    // 2。有resolved、rejected、pendding状态
    // 3。then方法有2个参数,可以获得resolve的值
    class MyPromise{
      constructor(executor){
        this.status="pendding"
        this.value=""
        this.reason=""
        this.onResolvedCallbacks=[]
        this.onRejectedCallbacks=[]
        try {
          executor(this._resolve.bind(this),this._reject.bind(this))
        } catch (error) {
          this._reject(error)
          
        }
      }
      _resolve(value){
        if(this.status==='pendding'){
          this.status="resolved"
          this.value=value
          console.log('7');
          this.onResolvedCallbacks.forEach(fn=>{
            console.log('8',fn);
            fn()
          })
          console.log('5');
        }

      }
      _reject(reason){
        if(this.status==='pendding'){
          this.status='rejected'
          this.reason=reason
          this.onRejectedCallbacks.forEach(fn=>{
            fn()
          })
        }

      }
      then(onFullFilled,onRejected){
        if(this.status==='resolved'){
          onFullFilled(this.value)
        }
        if(this.status==='rejected'){
          onRejected(this.reason)
        }
        if(this.status==='pendding'){
          console.log('3',this.value,'-')
          
          this.onResolvedCallbacks.push(()=>{onFullFilled(this.value)})
          this.onRejectedCallbacks.push(()=>{onRejected(this.reason)})
        }


      }
    }
    let p1=new MyPromise((resolve,reject)=>{
      // resolve('1')
      // reject('err')
      console.log('1')
      setTimeout(() => {
        console.log('4');
        resolve('success')
      }, 1000);
    })
    console.log(p1,2) 
    p1.then(response=>{
      console.log('6');
      console.log(response);
    },err=>{
      console.log(err);
    })

你以为到这就大功告成了,额,,这只是个开始,还有then的链式调用,此部分我们下次另说。