手写Promise简易版

话不多说,直接上代码

通过ES5的模块化封装,向外暴露一个属性

(function(window){

  const PENDING = 'pending';

  const RESOLVED = 'fulfilled'

  const REJECTED = 'rejected'

  function MyPromise(excutor){

    const self = this;   //保存Promise对象,防止异步执行时,拿不到数据和方法,必要

    self.value = undefined;

    self.status = PENDING;

    self.callbacks = [] //当状态没有发生改变时,需要储存起回调函数, 在then方法中获取回调函数

    function resolve(value){

      self.value = value;

      self.status = RESOLVED;

      self.callbacks.map(cb => {

        setTimeout(() => { //定时器模拟异步执行,必须保证回调异步执行,否则顺序就乱了

           cb.onResolved(self.value)

        })

      }) //执行保存起来的成功回调函数

    }

     function reject(value){

      self.value = value;

      self.status = REJECTED ; 

      self.callbacks.map(cb => {

        setTimeout(() => {

          cb.onRejected (self.value)

        })

      })//执行保存起来的失败的回调函数

    }

    try{   //若在执行器函数中主动抛出错误,需要捕获错误,并把状态更改为rejected

      excutor(resolve,reject)

    } catch (error){

      reject(error)

    }

  }

  MyPromise.prototype.then = function( onResolved,onRejected ){

    const self = this//保存当前的Promise对象

    return new Promise(resolve,reject){

      onResolved = onResolved === 'function' ? onResolved : v => v

      onRejected  = onRejected === 'function' ? onRejected :  error => {throw error}  //实现异常透传

      //判断当前的状态

      //假如Promise执行的异步任务,then方法是同步方法,那么当时Promise的状态为pending,所以不能执行回调,此时需要保存

      if(self.status === PENDING){

        // 这里只是把回调保存了起来,并没有改变当前的Promise对象,所以得进一步处理,处理和成功得处理类似

        self.callbacks.push({onResolved,onRejected})  //保存每一个then方法为一个对象,包含onResolved,onRejected两个函数

      } else if(self.status === RESOLVED){

        //1. 保证then中的回调异步执行,加一个setTimeout

        //2. 在onResolved中如果主动抛出错误,需要捕获错误

        //3. 根据Promise对象返回的结果,来决定下一个then中执行成功还是失败的回调

        //4. 如果上一个Promise返回的是一个值,如return 2,那么直接用resolve(2)执行

        //5. 如果上一个Promise返回的是一个promise对象,那么要通过promise.then 来获取promise的执行结果

        setTimeout(() => {

          try { 

             const result = onResolved(self.value)

            if( result instanceof MyPromise){ //判断返回值是不是Promise对象

              //返回一个Promise对象

              result.then( 

                value => {  //返回值是Promise对象,并且是成功的,那么就会执行这一个函数

                  resolve(self.value)

                }  

                error => {  //返回值是Promise对象,并且是失败的,那么就会执行这一个函数

                  rejecte(self.value)

                }

              )  

            }else {  //返回的不是一个Promise对象

               resolve(self.value)

            }

          } catch (error) {

             //与成功的处理一样,只需要更改一下回调函数,太长就不写了

          }

        })

      } else { //rejected状态}  

      }

    }

  window.MyPromise = MyPromise //向外暴露方法

})(window)

 

到这里就差不多写完简易的promise了,了解了原理也能更好的使用promise

欢迎指正,若有不清楚,也可评论指出

posted @ 2020-03-30 19:33  小白白又白啦  阅读(887)  评论(0编辑  收藏  举报