有关try catch的用法以及分析

示例1 :使用 try catch

执行后会在 catch 里捕获 请求异常,然后 getUserInfo 函数中断执行,这是符合逻辑的,对于有依赖关系的接口,中断执行可以避免程序崩溃,这里唯一的问题是 try catch 貌似占据了太多行数,如果每个接口都写的话看起来略显冗余。

function getUserInfo () {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      reject('请求异常')

    }, 1000)

  })

}

async function getLogin () {

  try {

    let userInfo = await getUserInfo()

    // 执行中断

    let pageInfo = await getPageInfo(userInfo?.userId)

  } catch(e) {

    console.warn(e)

  }

}

getLogin ()

示例2: 直接 catch

鉴于正常情况下,await 命令后面是一个 Promise 对象, 所以上面代码可以很自然的想到优化方案:

function getUserInfo () {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      reject('请求异常')

    }, 1000)

  })

}

async function getLogin () {

  let userInfo = await getUserInfo().catch(e => console.warn(e))

  // 执行没有中断,userInfo 为 undefined

  if (!userInfo) return // 需要做非空校验

  let pageInfo = await getPageInfo(userInfo?.userId)

}

getLogin ()

执行后 catch 可以正常捕获异常,但是程序没有中断,返回值 userInfoundefined, 所以如果这样写的话,就需要对返回值进行非空校验, if (!userInfo) return 我觉得这样有点反逻辑,异常时就应该中断执行才对;

示例3:在 catch 里 reject

可以继续优化,在 catch 里面加一行 return Promise.reject(e), 可以使 await 中断执行;

完整代码:

function getUserInfo () {

  return new Promise((resolve, reject) => {

    setTimeout(() => {

      reject('请求异常')

    }, 1000)

  })

}

async function getLogin () {

  let userInfo = await getUserInfo().catch(e => {

    console.warn(e)

    return Promise.reject(e) // 会导致控制台出现 uncaught (in promise) 报错信息

  })

  // 执行中断

  let pageInfo = await getPageInfo(userInfo?.userId)

}

getLogin ()

一般我们在项目里都是用 axios 或者 fetch 之类发送请求,会对其进行一个封装,也可以在里面进行 catch 操作,对错误信息先一步处理,至于是否需要 reject,就看你是否想要在 await 命令异常时候中断了;不使用 reject 则不会中断,但是需要每个接口拿到 response 后先 非空校验, 使用 reject 则会在异常处中断,并且会在控制台暴露 uncaught (in promise) 报错信息。

function getUserInfo () {
return new Promise((resolve, reject) => {
    setTimeout(() => {
     reject(请求异常')
      ,1000)
async function getLogin () {
     let userInfo = await getUserInfo().catch(e => {
      // 会导致控制台出现 uncaught (in promise) 报错信息
     console.warn(e)return Promise.reject(e)
   })
   //执行中断
   let pageInfo = await getPageInfo(userInfo?.userId)
}


    getLogin ()
....Promise {<pending>}
      //请求异常
.... Uncaught (in promise) //请求异常

建议

不需要在 await 处异常时中断,可以这样写,需要做非空校验,控制台不会有报错信息

let userInfo = await getUserInfo().catch(e => console.warn(e))

if (!userInfo) return

需要在 await 处异常时中断,并且在意控制台报错,可以这样写

try {

  let userInfo = await getUserInfo()

  // 执行中断

  let pageInfo = await getPageInfo(userInfo?.userId)

} catch(e) {

  console.warn(e)

}

需要在 await 处异常时中断,但是不在意控制台报错,则可以这样写

let userInfo = await getUserInfo().catch(e => {

  console.warn(e)

  return Promise.reject(e) // 会导致控制台出现 uncaught (in promise) 报错信息

})

// 执行中断

let pageInfo = await getPageInfo(userInfo?.userId)

总结

从用户体验上来看,有可能 try catch 是最好的,逻辑直观、符合同步编程思维,控制台不会暴露 uncaught (in promise) 报错信息;

而链式调用的 catch (里面再 reject),是传统 promise 的回调写法,既然已经用 async await 这种同步编程写法了,再用 catch 链式写法,没必要。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值