问题一
我们先了解一下 try catch
主要捕获的内容的指的是什么?
- 同步
- 异步
答案是:try catch
只能捕获同步的错误
// 这种情况setTimeout 为异步程序,捕获不了里面错误的逻辑
try {
setTimeout(() => {
throw new Error('e');
}, 100);
} catch (e) {
console.log('catch:', e);
}
// 正确的改写为,在异步执行结束后,同步的代码里面进行捕获
setTimeout(() => {
try {
throw new Error('e');
} catch (e) {
console.log(e);
}
}, 100);
问题二
一般JavaScript中会出现的错误类型有哪些,为什么要用到async await
答:
- 一般情况下会有同步和异步的错误
- 同步的错误一般的包括js书写错误导致以及程序执行不了的报错
- 异步的报错主要包括异步程序的执行错误,服务返回的接口调用出现的错误
- 接口调用一般情况下会使用异步的方法比如
promise
和async await
针对 XMLHTTPRequest进行封装 - 而
async await
的出现是为了解决回掉地狱以及多个promise
调用出现的问题
问题三
那我们一般怎么解决异步的报错呢?
方法有很多种
- 可以使用
try catch
- 在异步执行结束后在返回的同步代码中进行捕获
- 可以直接将
await
方法添加到try
当中 进行错误捕获,前提是await中的方法需要有reject 的错误抛出
-
promise
封装的方法自带有catch
的调用方法可以捕获到报错 - 可以使用全局错误捕获拦截
- 同步的使用
window.onerror = function(event){},
也可以使用dom2级 - 异步的使用
window.addEventListener('unhandledrejection', function (event) {})
具体要结合业务场景进行修改
// 中间有报错中断执行走error
try {
const list = await getList()
// 有报错执行中断
const info = await getListByName(list[0]?.name)
} catch (error) {
console.warn('报错的原因:', error)
}
// 业务判断loading 显示和消失
loading.value = true
let res = await getList().catch(() => (loading.value = false))
if (!res) return
同时有网友提出可以通过插件更便捷的对错误进行捕获
- 写太多的
try catch
影响阅读,可以引入插件进行执行await-to-js
// await-to-js 插件
/**
* @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
import to from 'await-to-js'
const [err,res] = to(Promise)
- 同时也可以在编译的时候,通过
babel
插件在编译的时候针对async await
方法 将内容代码通过try catch
进行包裹 地址
// babel 插件 babel-plugin-await-add-trycatch
npm install --save-dev babel-plugin-await-add-trycatch
// babel.config.js
module.exports = {
plugins: [
[
require('babel-plugin-await-add-trycatch'),
{
exclude: ['build'], // 默认值 ['node_modules']
include: ['main.js'], // 默认值 []
customLog: 'My customLog' // 默认值 'Error'
}
]
]
};
// 转化前
async function fn() {
await new Promise((resolve, reject) => reject('报错'));
await new Promise((resolve) => resolve(1));
console.log('do something...');
}
fn();
// 转化后
async function fn() {
try {
await new Promise((resolve, reject) => reject('报错'));
await new Promise((resolve) => resolve(1));
console.log('do something...');
} catch (e) {
console.log('\nfilePath: E:\\myapp\\src\\main.js\nfuncName: fn\nError:', e);
}
}
fn();