在 javascript 异步错误处理中,try-catch 无法直接捕获动态执行错误,因为 try-catch 仅适用于同步代码块。要捕获异步操作中的错误,必须使用 promise 的 .catch() 方法、async/await 配合 try-catch,或事件监听器如 unhandledrejection。

为什么 try-catch 不能捕获异步错误
try-catch 只能捕获同步代码中立即抛出的异常。当代码包含 setTimeout、Promise 或 fetch 等异步操作时,这些操作会将任务推入事件循环队列,而 try-catch 块会在异步任务执行前就结束运行。因此,异步回调中抛出的错误会脱离 try-catch 的控制范围,导致未捕获的异常。

function syncError() {
throw new Error('Sync error');
}
function asyncError() {
setTimeout(() => {
throw new Error('Async error');
}, 1000);
}
try {
syncError(); // 被捕获
asyncError(); // 抛出但未捕获
} catch (e) {
console.log(e.message); // 只打印 'Sync error'
}
上述代码中,syncError 的异常被正确捕获,但 asyncError 的异常未被处理,会导致控制台报错。这证明了 try-catch 对异步错误的局限性。
立即学习“Java免费学习笔记(深入)”;
如何使用 async/await 捕获异步错误
async/await 是处理异步错误的推荐方式,它允许开发者使用传统的 try-catch 语法来捕获异步操作中的错误。当 await 关键字等待一个拒绝的 Promise 时,它会抛出错误,从而被外层的 try-catch 块捕获。这种方式使异步代码看起来像同步代码,提高了可读性和可维护性。

async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Fetch error:', error.message);
}
}
fetchData();
在这个示例中,fetch 请求可能因网络问题或服务器错误而失败。通过 try-catch 包裹 await 调用,任何拒绝的 Promise 都会被捕获并处理。如果 fetch 返回非 200 状态码,手动抛出的错误也会被同一 catch 块捕获。这种模式确保了所有异步错误都能被统一处理。
如何处理 Promise 链中的动态错误
在 Promise 链中,动态错误可以通过在每个 then 后附加 .catch() 来处理,或者在链末尾添加统一的错误处理器。每个 .catch() 可以捕获前一个 Promise 的错误,并可以选择性地继续链式调用。这种方式提供了细粒度的错误控制,适合需要针对不同错误类型采取不同行动的场景。
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) throw new Error('HTTP error');
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Promise chain error:', error.message);
});
此代码展示了如何在 Promise 链中处理错误。第一个 .catch() 捕获 HTTP 错误,第二个 .catch() 捕获 JSON 解析错误。如果希望统一处理所有错误,可以在链末尾只保留一个 .catch()。这种灵活性使得开发者可以根据需求选择错误处理策略。


















