捕获并处理异常,能避免出现页面白屏的情况。那怎么捕获异常呢?

主动捕获运行时异常

try-catch 能捕获同步代码的运行时错误。如果是异步代码,需要转化成 await 的写法。如:

  1. try {
  2. doSth()
  3. await doSth2()
  4. } catch (e) {
  5. // 处理异常
  6. }

处理意料之外的全局运行时异常

未被处理的 JavaScript 运行时错误(包括语法错误)发生时, window 会触发 error 事件。处理异常:

  1. window.addEventListener(
  2. 'error',
  3. (e) => {/* 处理异常 */}
  4. )

当一项资源(如<img><script>)加载失败,加载资源的元素会触发 error 事件。处理异常:

  1. const img = new Image();
  2. img.addEventListener(
  3. 'error',
  4. (e) => {/* 处理异常 */}
  5. )
  6. img.src = 'xxx'

异步代码: Promise reject 的处理

Promise 被 reject 时,可以在 then 的第二个参数或 catch 中处理。如:

  1. p().then(onSuccess, onReject)
  2. p().catch(onReject)

Promise reject 没有被处理的话,window 会触发 unhandledrejection 事件。可以统一来处理:

  1. window.addEventListener(
  2. 'unhandledrejection',
  3. (e) => {/* 处理异常 */}
  4. )

用 Axios 时,接口报错的通用处理

可以在 Axios 接口返回的拦截器中,加入接口报错的通用处理。例如:

  1. axios.interceptors.response.use(function (response) {
  2. return response;
  3. }, err => {
  4. // 报错处理
  5. if(err.response) {
  6. switch (err.response.status) {
  7. case 400: err.message = '请求错误(400)'; break;
  8. case 500: err.message = '服务器错误(500)'; break;
  9. // ...
  10. }
  11. }
  12. return Promise.reject(error);
  13. })

Vue 的异常处理

  1. app.config.errorHandler = (err, vm, info) => {
  2. // 处理异常
  3. }

React 的异常处理

React 的生命周期函数 ComponentDidCatch 可以捕获子组件的异常。因此,可以在根组件外包裹一个组件来处理错误。如:

  1. class ErrorBoundary extends React.Component {
  2. componentDidCatch(error, info) {
  3. // 处理异常
  4. }
  5. }

使用:

  1. <ErrorBoundary>
  2. <App />
  3. </ErrorBoundary>

参考文档