Promise 捕获错误

你好,我是南一。这是我在准备面试八股文的笔记,如果有发现错误或者可完善的地方,还请指正,万分感谢🌹

前言:今天做项目时,遇到Promise抛出错误捕获不到的情况,然后我就去找了,阮一峰ES6入门重新学了一遍,又加深了对Promise的理解,分享给大家,望斧正!

先来看一段代码,创建一个Promise实例,状态设置为成功fulfilled

 const pro = new Promise((resolve, reject) => {
    resolve('我成功啦')
 })
 ​
 pro.then((res) => {
   console.log("then: " + res);
 }).catch((err) => {
   console.log('catch: ' + err);
 })
 //运行结果//then: 我成功啦

Promise构造函数传入一个函数,函数有两个参数:

  • resolveresolve函数的作用是,Promise对象的状态从“未完成”变为“成功” (即从 pending 变为 fulfilled),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
  • rejectreject函数的作用是,Promise对象的状态从“未完成”变为“失败” (即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

我成功啦 通过resolve函数,传递出去,被then方法接收到,then方法第一个参数是fulfilled状态的回调函数,所以就将 我成功啦 作为参数 res 打印出 then: 我成功啦

如果传入的函数抛出错误呢?

 const pro = new Promise((resolve, reject) => {
    //resolve('我成功啦')
    throw Error('请求超时')
 })
 ​
 pro.then((res) => {
   console.log("then: " + res);
 }).catch((err) => {
   console.log("catch: " + err);
 })
 //运行结果//catch: Error: 请求超时

现在我要把pro对象状态改变后的结果传递出去:我用returnPromise函数将pro对象调用then或catch方法后的结果 return 出去

 const pro = new Promise((resolve, reject) => {
     //resolve('我成功啦')
     throw Error('请求超时')
 })function returnPromise() {
   return pro.then((res) => {
     console.log("then: " + res);
     return res
   }).catch((err) => {
     console.log('catch: ' + err);
     return err;
   })
 }returnPromise().then((res) => {
   console.log('returnPromise then resolve: ' + res);
 }).catch((err) => {
   console.log('returnPromise catch: ' + err);
 })
 //运行结果 //catch: Error: 请求超时
           //returnPromise then resolve: Error: 请求超时 

诶,有点奇怪,抛出的错误在returnPromise内会被catch捕获到,而在外部调用后是在then方法内打印出来。

这里千万别搞混了,pro对象此时的状态是rejected,所以被catch捕获到,这很合理

解释:

Promise.prototype.catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

pro对象调用catch方法后返回,一个新的Promise对象(这里的catch方法其实就是then方法,因此也是返回一个新的Promise对象)

解释:

then方法返回的是一个新的Promise对象(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

因此,这个新的Promise对象调用then方法而不调用catch方法,是因为其状态为fulfilled(这里我还不知道为什么是fulfilled状态)

查完原因回来了 😁

根据Promise A+规范 (注释中的数字就是规范里的序号) then方法必须返回一个新的Promise对象

  promise2 = promise1.then(onFulfilled, onRejected); //2.2.7
  1. 如果then方法里的两个参数onFulfilledonRejected其中一个返回一个值x,则运行 Promise Resolution Procedure [[Resolve]](promise2, x)
  1. 如果其中一个onFulfilledonRejected抛出异常e,则promise2必须以e为理由来进入rejected状态。
  1. 如果onFulfilled不是一个函数且promise1状态为fulfilledpromise2必须是fulfilled状态,且跟promise1有着一样的value
  1. 如果onRejected不是一个函数且promise1状态为rejectedpromise2必须是rejected状态,且跟promise1有着一样的reason

"value” is any legal JavaScript value (including undefined, a thenable, or a promise).

“reason” is a value that indicates why a promise was rejected.

所以,pro对象调用catch方法后,catch方法return err,符合了第 1 点规则,因此,调用returnPromise()直接返回一个fulfilled状态的 Promise 对象,且参数为err

怎么让returnPromise方法调用后走catch方法呢?

returnPromise内部调用catch方法后,返回一个rejected状态的Promise实例对象

 const pro = new Promise((resolve, reject) => {
   throw Error('请求超时')
 })function returnPromise() {
   return pro.then((res) => {
     console.log("then: " + res);
     return res
   }).catch((err) => {
     console.log('catch: ' + err);
     //return err;
     return Promise.reject(err) //2.3.2
   })
 }returnPromise().then((res) => {
   console.log('returnPromise then resolve: ' + res);
 }).catch((err) => {
   console.log('returnPromise catch: ' + err);
 })
 //运行结果 //catch: Error: 请求超时
          //returnPromise catch: Error: 请求超时

pro对象catch方法返回一个值x (这里xPromise.reject(err),一个rejected状态的Promise对象) 则执行[[Resolve]](promise, x),并把新的promise对象的状态,置为跟x一样的rejected状态

那么如果在then方法内加上rejected状态的回调函数会怎么样呢?

前面我们说:Promise.prototype.catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

 const pro = new Promise((resolve, reject) => {
   throw Error('请求超时')
   // resolve('我成功啦')
 })function returnPromise() {
   return pro.then((res) => {
     console.log("then: " + res);
     return res
   }).catch((err) => {
     console.log('catch: ' + err);
     // return err;
     return Promise.reject(err)
   })
 }returnPromise().then((res) => {
   console.log('returnPromise then resolve: ' + res);
 }, (rej) => {
   console.log('returnPromise then reject: ' + rej);
 }).catch((err) => {
   console.log('returnPromise catch: ' + err);
 })
 //运行结果 //catch: Error: 请求超时
          //returnPromise then reject: Error: 请求超时

结果是在then方法内rejected状态的回调函数捕获到错误

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值