javascript 实现Promise.prototype.catch

实现Promise.prototype.catch

catch方法的实现非常简单,它的作用用于捕获一段Promise程序的异常,通常我们会将它放到Promise调用链的最下方。之所以说它非常简单因为这个作用已经被then方法实现了,所以我们只需要对then方法进行下包装即可:

MyPromise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected);
};

如果您没有理解上面的实现,可以返回到上面构造函数和then方法实现中仔细查看一下回调函数的调用过程以及出现异常时的应对方法。关于catch方法的调用机制,我们以以下规则进行处理异常:

  1. 如果Promise的执行状态为rejected,那么并不会直接决定接下来的Promise是否为rejected,而是同resolved状态一样,根据函数的执行结果决定。这条非常重要,我在这里再次重复一遍;
  2. 我们在then方法中对传入的onRejected回调方法进行了判断,如果其不为一个函数,我们会规定它的默认行为为直接抛出拿到的拒因,这也是为什么Promise的拒因可以一直穿透到最下方的catch方法中的原因。但是,正如我们上一条规则所提到的,如果您一旦指定了onRejected,下方的then方法就会根据传入的回调函数的执行结果来决定执行状态。简单得说就是,如果在catch方法的上方,有其它onRejected对拿到的拒因进行了处理,并且该过程并没有发生或者主动抛出异常,最下方的catch是不会拿到拒因的。

我的文字描述可能不能直接让您理解这个理念,您可以结合下方这段代码来进行理解:

let asyncCode = new Promise((resolve, reject) => {
  setTimeout(() => {
    // 这里的失败态会调用第一个then方法中的onRejected()
    reject(1);
  });
});

asyncCode.then(
  (value) => {
    // 不会执行
    console.log(e);
  },
  (reason) => {
    // 我们覆盖了onRejected的默认行为,但是我们主动抛出了异常
    throw reason;
  }
).then(
  (value) => {
    // 这里的代码同样不会执行
  },
  (reason) => {  // *
    // 我们在这里对拿到的拒因进行了操作,并且这段代码不会抛出异常(尽管它看起来很蠢)
    console.log(reason + "2"); // 输出:"12"
  }
).catch((e) => {
  // 所以这里的代码是不会执行的,因为上面的onRejected()执行结果(返回值)为undefined
  console.log(e + 1);
});

但是如果将标记*的失败处理函数删掉或者在其中使用throw主动抛出了错误,又或者是该函数中的逻辑代码出现了异常,下方的catch就会被执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值