捕获并处理异常,能避免出现页面白屏的情况。那怎么捕获异常呢?
主动捕获运行时异常
用 try-catch
能捕获同步代码的运行时错误。如果是异步代码,需要转化成 await
的写法。如:
try {
doSth()
await doSth2()
} catch (e) {
// 处理异常
}
处理意料之外的全局运行时异常
未被处理的 JavaScript 运行时错误(包括语法错误)发生时, window 会触发 error 事件。处理异常:
window.addEventListener(
'error',
(e) => {/* 处理异常 */}
)
当一项资源(如<img>
或<script>
)加载失败,加载资源的元素会触发 error 事件。处理异常:
const img = new Image();
img.addEventListener(
'error',
(e) => {/* 处理异常 */}
)
img.src = 'xxx'
异步代码: Promise reject 的处理
Promise 被 reject 时,可以在 then 的第二个参数或 catch 中处理。如:
p().then(onSuccess, onReject)
p().catch(onReject)
Promise reject 没有被处理的话,window 会触发 unhandledrejection
事件。可以统一来处理:
window.addEventListener(
'unhandledrejection',
(e) => {/* 处理异常 */}
)
用 Axios 时,接口报错的通用处理
可以在 Axios 接口返回的拦截器中,加入接口报错的通用处理。例如:
axios.interceptors.response.use(function (response) {
return response;
}, err => {
// 报错处理
if(err.response) {
switch (err.response.status) {
case 400: err.message = '请求错误(400)'; break;
case 500: err.message = '服务器错误(500)'; break;
// ...
}
}
return Promise.reject(error);
})
Vue 的异常处理
app.config.errorHandler = (err, vm, info) => {
// 处理异常
}
React 的异常处理
React 的生命周期函数 ComponentDidCatch
可以捕获子组件的异常。因此,可以在根组件外包裹一个组件来处理错误。如:
class ErrorBoundary extends React.Component {
componentDidCatch(error, info) {
// 处理异常
}
}
使用:
<ErrorBoundary>
<App />
</ErrorBoundary>