Skip to content

async await 全局异常捕获

一、需求背景

1.1 promise/async/await 的使用场景

js
// 封装一个基于Promise的请求函数
httpTest(status) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (status === 'success') {
        resolve({ code: 200, msg: '操作成功' });
      } else {
        reject('error');
      }
    }, 300);
  });
}

当我们使用.then().catch()的方法调用,我们在 catch 中就可以捕获到异常

js
// 调用方式一(封装的 httpTest 函数):
getList2() {
  this.httpTest()
    .then(res => {
      console.log(res);
    })
    .catch(err => {
      console.log(err);
    });
},

以下方式使用 async/await 无法捕获异常

js
// 调用方式二(封装的 httpTest 函数):
async getList3() {
  let res = await this.httpTest();
  console.log(res);
},

注意

调用方式二是不能捕获异常的!

1.2 async/await 如何捕获异常

js
// 方式一:调用后加catch
async getList4() {
  let res = await this.httpTest().catch(err => console.log(err));
  console.log(res);
},

// 方式二:try/catch包裹
async getList5() {
  try {
    let res = await this.httpTest();
    console.log(res);
  } catch (err) {
    console.log(err);
  }
},

async/await 捕获异常的两种方式中,方式二(try/catch)看起来更舒服些。

注意

方式二存在一个问题,如果页面中有多个请求方法时,难道每个请求都使用 try/catch 来包裹吗?这样就会出现 try/catch 满天飞的情况。

二、实现方式

解决 try/catch 满天飞的方式如下

js
/**
 * 方式一:封装
 * 全局的异常捕获
 * @param {Function} func 传入的方法
 * @param  {...any} args 方法调用的参数
 * @returns {Array} [err, res]
 */
export async function asyncFunc(func, ...args) {
  try {
    const res = await func(...args)
    return [null, res]
  } catch (e) {
    return [e, null]
  }
}

// 调用
import asyncFunc from 'xxxx/xxx/xxx'
import { apiOne, apiTwo } from 'api/index.js'
async function func() {
  // A:不带参数接口的处理
  const [err, res] = await asyncFunc(apiOne)
  if (err) {
    // 错误处理
  }
  // 正常处理

  // B:带参数接口的处理
  const [api2Err, api2Res] = await asyncFunc(apiTwo, {id: xxx}, list: [1,2,3,4,5], isTrue: true)
  if (api2Err) {
    // 错误处理
  }
  // 正常处理
}

错误可以在 asyncFunc 进行定义全局捕捉,毕竟 async...await...的应用场景大多是连锁请求。

js
// 方式二:使用第三方插件
// Step 1: 引入
yarn add await-to-js

// Step 2:使用
import awaitTo from "await-to-js"

const [err, res] = await awaitTo(getResData(url, params))
if(err) {
  // 错误处理
} else {
  // 正常处理
}

三、备注