try-catch仅捕获同步异常,对异步错误、语法错误、未await的Promise、事件处理器内错误无效;需await才能捕获async/await中的Promise错误;catch参数可解构但须注意兼容性;finally适合清理但不应抛错或引入新异常。
try-catch 只捕获**同步执行中抛出的异常**,比如 throw new Error()、类型错误(TypeError)、引用错误(ReferenceError)等。它对以下情况完全无效:
setTimeout、fetch 回调、Promise 拒绝)SyntaxError)——脚本根本不会执行到 try 块try 内创建了 Promise,不 await 或不加 .catch() 就会漏掉)onclick 中抛错,除非你在 handler 内部手动包 try-catch)写 async 函数时,try-catch 只对 await 的 Promise 生效;漏掉 await 就等于把 Promise 当普通对象返回,错误不会进入 catch。
async function bad() {
try {
fetch('/api'); // ❌ 没 await,fetch 返回 Promise 但不等待,错误被忽略
} catch (e) {
console.error(e); // 这里永远不会执行
}
}
async function good() {
try {
const res = await fetch('/api'); // ✅ await 后,网络错误、4xx/5xx 都进 catch
if (!res.ok) th
row new Error(`HTTP ${res.status}`);
} catch (e) {
console.error('请求失败:', e.message);
}
}
catch 后的参数只是形参,名字任意,但必须存在。常见写法是 catch (error) 或 catch (e),但要注意:
catch (err.message) —— 这是语法错误,JS 不支持解构式捕获catch ({ message, name }) 来直接解构错误对象属性(ES2015+ 支持)error instanceof Error,再访问 message,因为某些错误(如字符串 throw 'oops')没有 message 属性finally 总会执行,适合关流、重置状态、隐藏 loading 等。但要注意:
finally 中 throw 或返回 rejected Promise,它会覆盖 try 或 catch 中的返回值或错误finally 里做可能失败的操作(比如又发一个可能出错的 fetch),否则会掩盖原始错误loading.value = false
catch 打印 e.message,大概率查不到问题源头。需要主动保留 e.stack,并在日志中透出完整信息。