符合PromiseA+规范并不代表与浏览器表现一致

引出问题

不处理reject,浏览器会抛异常吗?

考虑下列代码的执行情况

new Promise(function(resolve, reject) {
    reject('reason')
})
复制代码

很多同学估计都会去Chrome的控制台输出一下,发现这段代码其实会往外抛一个异常

但是参考一个通过Promise/A+规范测试的Promise的源码,发现其reject并没有往外抛出异常

function reject(reason) {
    if (self.status === 'pending') {
    // 改变状态
      self.status = 'rejected'
    //   保持值
      self.data = reason
    //   执行回调
      for(var i = 0; i < self.onRejectedCallback.length; i++) {
        self.onRejectedCallback[i](reason)
      }
    }
  }
复制代码

参考文章: 剖析Promise内部结构,一步一步实现一个完整的、能通过所有Test case的Promise类(目前大部按照PromiseA+规范实现Promise的文章,代码基本都是这样的,其中这篇讲解比较详细,具有代表性)

查阅了一下PromiseA+的规范,其实并没有规定reject要向外抛出错误

各个引擎中的表现

  • Nodejs
    Nodejs和Chrome一样,也是基于v8的JS引擎。所以首先看看再Nodejs下的表现

  • Edge
    没抛异常,且IE看不到Promise的状态

  • Firefox

为什么

promise-polyfill库中找到了这样的方法

大意就是,在reject里面会执行Promise._unhandledRejectionFn方法,由用户自己决定怎么处理这个reject的异常。显然大多数浏览器原生Promise的选择是,如果没有catch进行处理,就抛出

总结

  1. 其实,一般情况下,规范的使用catch就不会有上述问题了。在reject的情况下,只要后面有catch处理,就不会抛出异常。没有catch的情况下,一般会往外抛异常
  2. 在then的回调函数中,如果出现了异常且后面没有catch,还是会向外抛出异常,所以合理使用catch是很重要的
  3. 最后,并不是说讲解Promise实现的文章不好,而是PromiseA+没有明确指出上述情况,所以希望读者能够了解到浏览器上的表现差异。

转载于:https://juejin.im/post/5c2ec253e51d45522f564ae4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值