首先,让我解释一下,try-catch 处理没有错。我认为以这种方式编写代码会有点混乱。我觉得代码的逻辑被破坏了,很难理解。
二是代码冗余问题。单个 try-catch 会占用多行代码。如果向每个请求添加了 try-catch,则代码将显示为臃肿。
而对于如此大量的相同冗余代码,可以用通用功能代替。
async/await 在 ES2017 中引入,旨在让异步操作更加直观方便,并解决 Promise 回调地狱问题。
1. 何时申请例外
我们都知道,这通常跟着异步请求。异步请求异常的原因大致如下:await
由于网络问题,网络断开连接,请求不可用
慢速网络会导致异步请求超时。
2. 在什么情况下需要处理请求异常?
一旦出现上述情况,异步请求就会产生异常,JavaScript 是一种单线程语言。代码报错后,后续代码无法继续执行,此时需要添加 try-catch 来捕获异步请求。异常,以便代码可以继续向后执行。
但是,是否有必要为所有异步请求添加 try-catch?
我研究了我们项目的代码。异步请求使用 try-catch 进行处理。有以下几种情况。
2.1 多异步请求串行
try { const list = await getList(params) const info = await getListById(list[0]?.id)} catch {}
上一个异步请求的返回结果会作为下一个异步请求的请求参数,所以一旦上一个请求异常,后续请求就会异常,所以需要添加 try-catch 处理。
2.2 处理异步请求的加载状态
loading.value = truetry { const list = await getList(params)} finally { loading.value = false}
一般来说,在我们处理异步请求之前,我们会给它添加一个加载状态,一旦出现请求异常,如果我们不添加 try-catch,页面将始终处于加载状态。因此,最后需要将加载状态设置为 false,并且在 catch 中处理时需要外部处理。
那么,我们如何优雅地处理异步请求中的 try-catch?
3. 处理承诺
首先,需要明确的是:在正常情况下,await 命令后面跟着一个 Promise 对象。因此,它可以使用自身来捕获异常。就像上面第二个只处理加载状态的操作一样,可以在 .catch 中处理,然后使用 if 判断来控制提前退出。无需编写 try-catch 冗余代码。.catch
loading.value = truelet res = await getList().catch(() => (loading.value = false))if (!res) return
**await-to-js**
处理程序函数
我们可以将上述方法用于简单的异步请求,但是当遇到多个异步操作时,我们需要使用我们今天要讨论的库。它的介绍非常简单:可以轻松执行,而不会发生 try-catch 句柄错误。await-to-js
而且源码很简单,只有23行代码,一起来看看吧。
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
一般流程如下:接受参数 Promise 和 .如果承诺成功,它将返回 。如果异常,它将判断它是否有参数(表示传递给 err 对象的附加信息)。如果它有时与捕获返回捕获的错误合并,或者如果没有。errorExt``[null, data]``errorExt``[err, undefined]
4. 如何使用
4.1 安装
# use npmnpm i await-to-js --save# use yarnyarn add await-to-js
4.2 使用
首先介绍一下to函数,可以看到包很小,只有370b,gzip压缩后只有242b,所以随意导入,不用担心包大小。
我们用来重写上面的第一个问题:
import to from const [err, data] = await to(getList(params))if (err) returnconst info = await to(getListById(list[0]?.id))
函数转换后,如果返回的第一个参数不为空,则表示请求报错,可以提前返回。如果没有第一个参数,则异步请求成功。to