【JavaScript】Try-Catch 在多层嵌套下的处理结果

161 阅读4分钟

前言

try-catch 是 JavaScript 中用于错误处理的重要机制。它可以帮助我们捕获代码执行中的异常,并提供相应的处理逻辑。然而,当涉及到多层嵌套时,try-catch 的行为可能会变得复杂。本文将通过多个题目帮助你深入理解 try-catch 在多层嵌套下的处理结果。

基础篇

题目1:单层 try-catch

try {
  console.log("开始执行");
  throw new Error("出错了");
  console.log("这里不会执行");
} catch (e) {
  console.log("捕获到错误:", e.message);
}

答案
输出:

开始执行
捕获到错误: 出错了

题目2:嵌套 try-catch,内层捕获

try {
  console.log("开始执行");
  try {
    throw new Error("内层出错了");
  } catch (e) {
    console.log("内层捕获到错误:", e.message);
  }
  console.log("内层后续代码");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
内层捕获到错误: 内层出错了
内层后续代码

题目3:嵌套 try-catch,内层未捕获

try {
  console.log("开始执行");
  try {
    throw new Error("内层出错了");
  } catch (e) {
    throw e;
  }
  console.log("内层后续代码");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
外层捕获到错误: 内层出错了

进阶篇

题目4:嵌套 try-catch,外层捕获

try {
  console.log("开始执行");
  try {
    throw new Error("内层出错了");
  } catch (e) {
    console.log("内层捕获到错误:", e.message);
    throw new Error("外层抛出新错误");
  }
  console.log("内层后续代码");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
内层捕获到错误: 内层出错了
外层捕获到错误: 外层抛出新错误

题目5:嵌套 try-catch,内层捕获后继续执行

try {
  console.log("开始执行");
  try {
    throw new Error("内层出错了");
  } catch (e) {
    console.log("内层捕获到错误:", e.message);
    throw new Error("内层再次抛出错误");
  } finally {
    console.log("内层 finally 执行");
  }
  console.log("内层后续代码");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
内层捕获到错误: 内层出错了
内层 finally 执行
外层捕获到错误: 内层再次抛出错误

题目6:嵌套 try-catch,内层 finally 中抛出错误

try {
  console.log("开始执行");
  try {
    throw new Error("内层出错了");
  } catch (e) {
    console.log("内层捕获到错误:", e.message);
  } finally {
    throw new Error("finally 中抛出错误");
  }
  console.log("内层后续代码");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
内层捕获到错误: 内层出错了
外层捕获到错误: finally 中抛出错误

题目7:嵌套 try-catch,内层 finally 中返回值

try {
  console.log("开始执行");
  try {
    throw new Error("内层出错了");
  } catch (e) {
    console.log("内层捕获到错误:", e.message);
  } finally {
    return "finally 中的返回值";
  }
  console.log("内层后续代码");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
内层捕获到错误: 内层出错了

解释finally 中的返回值会覆盖外层的返回值,但外层的 catch 仍然会捕获到错误。

特殊场景篇

题目8:try-catch 中的 Promise

try {
  console.log("开始执行");
  Promise.reject("Promise 出错了").catch((e) => {
    console.log("Promise 捕获到错误:", e);
  });
  throw new Error("同步代码出错了");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
Promise 捕获到错误: Promise 出错了
外层捕获到错误: 同步代码出错了

题目9:try-catch 中的异步函数

async function test() {
  try {
    console.log("开始执行");
    await Promise.reject("Promise 出错了");
  } catch (e) {
    console.log("内层捕获到错误:", e);
  }
  throw new Error("同步代码出错了");
}

test().catch((e) => {
  console.log("外层捕获到错误:", e.message);
});

答案
输出:

开始执行
内层捕获到错误: Promise 出错了
外层捕获到错误: 同步代码出错了

题目10:try-catch 中的 setTimeout

try {
  console.log("开始执行");
  setTimeout(() => {
    throw new Error("setTimeout 中出错了");
  }, 0);
  throw new Error("同步代码出错了");
} catch (e) {
  console.log("外层捕获到错误:", e.message);
}

答案
输出:

开始执行
外层捕获到错误: 同步代码出错了

解释setTimeout 中的错误不会被外层的 try-catch 捕获,因为它是异步执行的。

综合挑战篇

题目11:多层嵌套 try-catch,异步与同步混合

async function test() {
  try {
    console.log("开始执行");
    try {
      await Promise.reject("Promise 出错了");
    } catch (e) {
      console.log("内层捕获到错误:", e);
    }
    throw new Error("同步代码出错了");
  } catch (e) {
    console.log("外层捕获到错误:", e.message);
  }
}

test().catch((e) => {
  console.log("最外层捕获到错误:", e.message);
});

答案
输出:

开始执行
内层捕获到错误: Promise 出错了
外层捕获到错误: 同步代码出错了

题目12:多层嵌套 try-catch,异步与同步混合,finally 干预

async function test() {
  try {
    console.log("开始执行");
    try {
      await Promise.reject("Promise 出错了");
    } catch (e) {
      console.log("内层捕获到错误:", e);
    } finally {
      throw new Error("finally 中抛出错误");
    }
    throw new Error("同步代码出错了");
  } catch (e) {
    console.log("外层捕获到错误:", e.message);
  }
}

test().catch((e) => {
  console.log("最外层捕获到错误:", e.message);
});

答案
输出:

开始执行
内层捕获到错误: Promise 出错了
外层捕获到错误: finally 中抛出错误

总结

这些如果全部看熟练了,业务上的大部分场景就都没问题了,有需要可以继续补充。

下次再见(●'◡'●)