1

关于try - catch

在请求时使用Promise返回,对返回结果做错误处理的一些小疑问

业务流程

  1. 接口请求
  2. 业务 api 层处理
  3. 业务逻辑页面层处理

模拟get请求方法

function get(url?: string) {
  return new Promise((resolve, reject) => {
    console.log("request url: " + url);
    setTimeout(() => {
      reject({ code: 400, msg: "fail" });
    }, 1000);
  });
}

api 层

async function api() {
  await get();
}

业务逻辑层

async function action() {
  await api();
}

情况 1

api 和业务层都没有try

async function api001() {
  console.log("api001 before");
  const res = await get();
  console.log("api001 after", res);
}
async function action001() {
  console.log("action001 before");
  await api001();
  console.log("action001 after");
}

// console.log
action001 before
api001 before
get
Uncaught (in promise)

有报错,但是这个错误是运行环境提示的错误

情况 2

api 和业务层都有try

async function api002() {
  try {
    console.log("api002 before");
    const res = await get();
    console.log("api002 after", res);
  } catch (err) {
    console.error("api002 error", err);
  }
}
async function action002() {
  try {
    console.log("action002 before");
    const res = await api002();
  } catch (err) {
    console.error("action002 error", err);
  }
}

// console.log
action002 before
api002 before
get
api002 error
action002 after

这个时候有报错,这个错误来自api. 而业务层往下执行,没有报错.

情况 3

api 没有try, 业务层有try

async function api003() {
  console.log("api003 before");
  const res = await get();
  console.log("api003 after", res);
}
async function action003() {
  try {
    console.log("action003 before");
    const res = await api003();
    console.log("action003 after");
  } catch (err) {
    console.error("action003 error", err);
  }
}

// console.log
action003 before
api003 before
get
action003 error

这时, 错误信息来自action,而且没有往下执行.

情况 4

api和业务层都有try, 但是在api层添加了一个错误时,抛出错误的操作.

async function api004() {
  try {
    console.log("api004 before");
    const res = await get();
    console.log("api004 after", res);
  } catch (err) {
    console.error("api004 error", err);
    return Promise.reject(err); // 返回一个错误
  }
}
async function action004() {
  try {
    console.log("action004 before");
    const res = await api004();
    console.log("action004 after");
  } catch (err) {
    console.error("action004 error", err);
  }
}

// console.log
action004 before
api004 before
get
api004 error
action004 error

这时, api和业务层都获取到错误.

总结

由于请求返回体一定会将错误信息返回, 所以api层报错时, 一定不会往下执行. 而api层可能有自己的错误处理(例如清空一些参数, 或者打印一些错误信息等), 因此需要使用try. 而业务层也可能有特殊处理(例如弹框提示, 设置业务层的 state 等), 所以在api层报错时, 需要返回Promise.reject来通知业务层报错信息.

  1. 加了try-catch的函数,在引用时,不会通知外层报错(让外层函数可以继续往下执行), 不加就会通知报错(在外层函数获取到错误).
  2. 加了try-catch,但是又想通知外层报错, 就再return一个Promise.reject.

具体情况具体分析.


darcrand
637 声望20 粉丝