译文: 停止使用try-catch来捕获Async/Await异常

首先,让我解释一下,try-catch处理没有什么问题。但是我觉得这种方式编写代码会显得有点混乱。我觉得代码的逻辑被破坏了,很难理解。

其次是代码冗余的问题。一个单独的try-catch占据了几行代码。如果每个请求都添加一个try-catch,代码会显得臃肿。

对于如此大量相同的冗余代码,可以通过一个通用函数来替代。在ES2017中引入了async/await,使异步操作更直观、方便,并解决了Promise回调地狱的问题。

1. 什么情况下需要使用try-catch ?

我们都知道,await通常后面会跟着异步请求,异步请求异常的原因大致如下:

  • 由于网络问题,网络断开连接,请求不可用
  • 缓慢的网络导致异步请求超时

2. 在什么情况下需要处理请求异常 ?

一旦出现上述情况,异步请求将生成一个异常,而JavaScript是一种单线程语言。在代码报告错误后,后续代码无法继续执行,因此此时需要添加try-catch来捕获异步请求的异常,以便代码可以向后继续执行。

但是,是否需要为所有异步请求都添加try-catch呢?

我研究了我们项目的代码,使用try-catch处理的异步请求,存在以下情况。

2.1 多个异步请求串行

js 复制代码
try {
  const list = await getList(params)
  const info = await getListById(list[0]?.id)
} catch {}

前一个异步请求的返回结果将被用作下一个异步请求的请求参数,因此一旦前一个请求异常,后续请求也将异常,因此需要添加try-catch处理。

2.2 处理异步请求的加载状态

js 复制代码
loading.value = true
try {
  const list = await getList(params)
} finally {
  loading.value = false
}

通常,在处理异步请求之前,我们会为其添加一个加载状态,一旦请求异常,如果不添加try-catch,页面将一直处于加载状态。因此,有必要在finally中将加载状态设置为false,并在catch中进行外部处理。

那么,我们如何优雅地处理异步请求中的try-catch呢?

3. 处理Promise

首先需要明确:在正常情况下,await命令后面跟着一个Promise对象。因此,它可以使用.catch自身来捕获异常。就像上面处理加载状态的第二个操作那样,它可以在.catch中处理,然后使用if判断来控制提前退出。没有必要编写try-catch的冗余代码。

js 复制代码
loading.value = true
let res = await getList().catch(() => (loading.value = false))
if (!res) return

await-to-js 处理方法

我们可以使用上述方法处理简单的异步请求,但是当遇到多个异步操作时,我们需要使用今天将要讨论的await-to-js库。它的介绍非常简单:可以轻松的在不使用try-catch的前提下执行错误处理。

源码也很简单,只有23行代码,让我们看下其实现原理。

ts 复制代码
/**
 * @param { Promise } promise
 * @param { Object= } errorExt - Additional Information you can pass to the err object
 * @return { Promise }
 */
export function to<T, U = Error>(
  promise: Promise<T>,
  errorExt?: object
): Promise<[U, undefined] | [null, T]> {
  return promise
    .then<[null, T]>((data: T) => [null, data])
    .catch<[U, undefined]>((err: U) => {
      if (errorExt) {
        const parsedError = Object.assign({}, err, errorExt)
        return [parsedError, undefined]
      }

      return [err, undefined]
    })
}

export default to

一般过程如下:函数to接受PromiseerrorExt两个参数。如果Promise成功,它返回null, data。如果异常,将判断是否有errorExt参数(表示传递给err对象的附加信息)。如果存在errorExt,会将其与catch捕获的err合并后返回,否则返回err, undefined

4. 如何使用

4.1 安装

sh 复制代码
# use npm
npm i await-to-js --save
# use yarn
yarn add await-to-js

4.1 使用

首先引入to函数,可以看到这个包非常小,只有370字节,gzip压缩后仅242字节,所以随意导入,不用担心包大小。

通过to函数的转换,如果返回的第一个参数不为空,说明请求报告了错误,可以提前返回。如果没有第一个参数,说明异步请求成功。

结语

最后感谢阅读,期待您的关注和阅读更多优质文章。

原文链接

如侵则删

相关推荐
郑州光合科技余经理44 分钟前
本地生活系统:多业务订单字段怎么分账本导出
java·开发语言·前端·数据库·uni-app·php·ai编程
怕浪猫7 小时前
FDE 如何正确解决现场项目工程性的问题
前端·后端·ai编程
西瓜太郎12348 小时前
外层模型卡片与分组详情成功率不一致,应该怎么排查?
前端·typescript·go·软件工程·react
GreenTea8 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
几何心凉11 小时前
没有万能模型:我用 AiiOnly Token Plan,把多款大模型的长处拼进同一个项目
前端
kyriewen11 小时前
Claude Code 的额度今天缩水了17%——官方公告上写的是"永久提高25%"
前端·ai编程·claude
雪芽蓝域zzs12 小时前
vue解构平铺VS对象包裹
前端·javascript·vue.js
风骏时光牛马13 小时前
从零到实战,完整AI学习路线
前端
三十而立洋13 小时前
深入理解 Monorepo:子包安装依赖
前端·前端工程化
IT_陈寒13 小时前
Java Stream处理大集合,我的内存怎么就炸了
前端·人工智能·后端