1. 前言
-
本文参加了由 公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
-
这是源码共读的第21期,链接:await-to-js
2. await-to-js
await-to-js
这个库解决了什么问题?
用于帮助处理基于 promise 的异步函数的错误和异常。
在 JavaScript 的 async/await
语法中,如果 await
的函数抛出一个错误,你必须使用 try/catch
语句来捕获并处理这个错误。
3. 源码解析
源码比较简单就是通过高阶函数传入执行函数,在内部通过try...catch
进行错误捕获,返回正常的数据。
js
function to<T, U = Error>(
promise: Promise<T>,
errorExt?: object
): Promise<[U, undefined] | [null, T]> {
// 返回promise
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];
});
}
场景应用:
在项目中,我们通过axios进行接口请求,当接口请求前需要loading
展示,接口正常时可以正常关闭。接口错误是如果不进行错误捕获,会一直加载中。
代码如下:
项目中使用code进行判断是否正常返回,所以代码改造和正常的返回格式保持一致。
js
// 未进行错误捕获
tableLoading = true
const res = axios('/api/getList')
if(res.code===1){
tableData = res.data
}
tableLoading = false
// 上面接口报错,阻塞后续代码执行,就需要添加错误处理
try{
tableLoading = true
const res = fetch('/api/getList')
if(res.code===1){
tableData = res.data
}
}finally{
tableLoading = false
}
所以参考await-to-js
进行改造
js
const axios = axios.create({
baseURL: process.env.VUE_APP_API,
})
axios.interceptors.request.use(
(config) => config,
(error) => Promise.reject(error)
)
axios.interceptors.response.use(
(response) => response,
(error) => Promise.reject(error)
)
async function request(method, url, config) {
try {
const res = await axios.request({
method,
url,
...config,
})
return res.data
} catch (error) {
// NOTE:拦截网络错误返回错误body
return {
code: 0,
errorCode: '',
errorDesc: '',
data: null,
msg: '网络错误',
error,
}
}
}
axios的错误传播链,参考下前端错误传播,通过上面的改造后,就不需要每次进行错误捕获。
4. 总结
本次学习主要有:
- 理解 JavaScript 中的错误处理和异常抛出机制
- 了解了错误优先回调(Error-First Callback)
- 对于错误的处理,都返回
[err,data]
适配了不同错误的处理,省略每次写try...catch
的烦恼
O^O!!!