查询:
为什么 try 块没有捕获 Javascript 中异步方法中的错误?可以从执行上下文的角度来理解吗?
有没有一种方法可以将所有错误处理包装在入口文件或更高级别?
上下文:在 PHP 中的多层应用程序(例如控制器、服务、DAO)中,控制器层中的伞式 try-catch 块可以捕获任何较低层中的错误。是否可以在 node.js 中做类似的事情?
查询:
为什么 try 块没有捕获 Javascript 中异步方法中的错误?可以从执行上下文的角度来理解吗?
有没有一种方法可以将所有错误处理包装在入口文件或更高级别?
上下文:在 PHP 中的多层应用程序(例如控制器、服务、DAO)中,控制器层中的伞式 try-catch 块可以捕获任何较低层中的错误。是否可以在 node.js 中做类似的事情?
@veryVerde 是正确的,您需要 await 或 .catch()。
这里有一篇文章解释了当你在 javascript 中抛出不同的上下文时会发生什么(注意这篇文章关注的是客户端,而不是 node.js):文章
这是一些代码,显示了在异步和承诺的各种排列中会/不会被捕获的内容。(或在 jsfiddle 上:https://jsfiddle.net/bricksphd/dwpocs7k/21/。)
async function f() {
//Throw without async or promise
try {
throw new ("Simple throw error: 1");
} catch (e) {
console.error("Caught in simple catch: " + e);
}
//
//Throw async...
//
//...inside a catch block w/o await w/o catch
try {
f = async () => {
throw ("Throw error in async w/o .catch: 2");
}
f();
} catch (e) {
console.error(e);
}
//...inside a catch block with w/o await with catch
try {
f = async () => {
throw "Async with .catch: 3";
}
f()
.then(result => console.log("No error"))
.catch(e => {console.log("Caught in promise.catch: " + e)});
} catch (e) {
console.error(e);
}
//...inside a catch block with await
try {
f = async () => {
throw ("Throw error with await/catch: 4");
}
await f();
} catch (e) {
console.error(e);
}
//
//Promises...
//
//... inside a catch block with .catch
try{
let p = new Promise((resolve, reject)=>reject("Reject with .catch: 5"));
p.then(resolve=>console.log("No error here.")).catch(e=>console.log(e));
} catch (e){
console.log("Caught Exception: " + e);
}
//... inside a catch block w/o .catch
try{
let p = new Promise((resolve, reject)=>reject("Reject w/o .catch: 6"));
} catch (e){
console.log("Caught Exception: " + e);
}
try{
let p = new Promise((resolve, reject)=>reject("Reject with await: 7"));
await p;
} catch (e){
console.log("Caught Exception: " + e);
}
}
f()
.then(result=>console.log("Didn't find any global errors"))
.catch(e=>console.log("Found uncaught error: " + e));
只有在所有同步代码完成运行后,才会解析 Promise。正如你所说,它可以理解为执行上下文。为了解决 Promise,它需要执行额外的步骤,例如暂停代码的执行。出于这个原因,除非您使用await
或回调 ( .catch(() => {...})
),否则您将无法按照您想象的方式捕获错误。
您可以在应用程序的顶层等待/回调所有异步进程,并添加一个执行函数的 try catch 块/catch 回调,但如果您使用 REST,则可能必须单独放置捕获。