Promise从两眼发懵到双眼放光(7)-手写Promise之then方法和catch方法

javascript/jquery

浏览数:275

2020-5-28

show you my code
/**  
 * Promise原型对象的then() 
 * @param onResolved 成功回调  
 * @param onRejected 失败回调  
 * @return Promise  
 */
 Promise.prototype.then = function (onResolved, onRejected) {  
   //向后传递成功的结果  
   onResolved = typeof onResolved === 'function' ? onResolved : value => value 
   //向后传递失败的结果  
   //指定默认的失败回调,此处是实现异常穿透的关键点  
   onRejected = typeof onRejected === 'function' ? onRejected : reason => {  
     throw reason  
   }  
  
   const self = this  
  
   //返回一个新的promise对象  
   return new Promise((resolve, reject) => {  
  
   /**  
    * 调用指定的回调函数,根据回调函数的执行结果,改变return的promise的状态 
    * @param callback  
    */  
   function handle(callback) {  
   /*  
    1. 如果抛出异常, return的promise就会失败, reason就是error 
    2. 如果回调函数返回不是promise, return的promise就会成功, value就是返回的值 
    3. 如果回调函数返回是promise, return的promise结果就是这个promise的结果 
   */  
   try {  
    const result = callback(self.data)  
    if (result instanceof Promise) {  
    //3.如果回调函数返回是promise, return的promise结果就是这个promise的结果  
    result.then(  
      // 当result成功时,return的promise成功  
      value => resolve(value),  
      // 当result失败时,return的promise失败  
      reason => reject(reason)  
    )  
    //简写方式  
    //result.then(resolve, reject)  
    } else {  
      //2. 如果回调函数返回不是promise, return的promise就会成功, value就是返回的值 
      resolve(result)  
    }  
  } catch (error) {  
    //1. 如果抛出异常, return的promise就会失败, reason就是error  
   reject(error)  
  }  
}  
  
    if (self.status === PENDING) {  
      //resovle/reject 已经将回调放入队列中了  
      self.callbacks.push({  
        onResolved() {  
          handle(onResolved)  
        },  
        onRejected() {  
          handle(onRejected)  
        }  
      })  
    } else if (self.status === RESOLVED) {  
      //如果当前是resolved状态, 异步执行onResolved并改变return的promise状态  
      setTimeout(() => {  
        handle(onResolved)  
      })  
    } else {  
      //如果当前是rejected状态, 异步执行onRejected并改变return的promise状态  
      setTimeout(() => {  
        handle(onRejected)  
      })  
    }  
  })  
}  
  
/**  
 * Promise原型对象的catch() 
 * @param onRejected 失败回调  
 * @return Promise  
 */
 Promise.prototype.catch = function (onRejected) {  
  return this.then(undefined, onRejected)  
}

测试

<!-- 引入手写Promise-->  
<script src="./3.Promise_then&catch方法.js"></script>  
  
<script>  
  new Promise(((resolve, reject) => {  
    setTimeout(() => {  
      // resolve(1)  
      reject(2)  
    },1000)  
  })).then(  
    value => {  
      console.log("onResolved1", value)  
    },  
    // reason => {  
    //   console.log("onRejected1", reason) 
    // }  
 ).then(  
    value => {  
      console.log("onResolved2", value)  
    },  
    // reason => {  
    //   console.log("onRejected2", reason) 
    // }  
 ).catch(reason => {  
    console.log('catch', reason)  
  }).then(  
    value => {  
      console.log("onResolved3", value)  
    },  
    reason => {  
      console.log("onRejected3", reason)  
    }  
  )
执行结果
catch 2
onResolved3 undefined
代码已同步更新到github

https://github.com/hnt815/promise

Promise系列文章

Promise从两眼发懵到双眼放光(1)-准备篇
Promise从两眼发懵到双眼放光(2)-Promise基础
Promise从两眼发懵到双眼放光(3)-Promise的几个关键问题(一)
Promise从两眼发懵到双眼放光(4)-Promise的几个关键问题(二)
Promise从两眼发懵到双眼放光(5)-手写Promise之整体结构
Promise从两眼发懵到双眼放光(6)-手写Promise之构造函数
Promise从两眼发懵到双眼放光(7)-手写Promise之then方法和catch方法
Promise从两眼发懵到双眼放光(8)-手写Promise之resolve,reject,all,race方法
Promise从两眼发懵到双眼放光(9)-async和await

作者:ntyang