0

查询:

  1. 为什么 try 块没有捕获 Javascript 中异步方法中的错误?可以从执行上下文的角度来理解吗?

  2. 有没有一种方法可以将所有错误处理包装在入口文件或更高级别?

上下文:在 PHP 中的多层应用程序(例如控制器、服务、DAO)中,控制器层中的伞式 try-catch 块可以捕获任何较低层中的错误。是否可以在 node.js 中做类似的事情?

4

2 回答 2

0

@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));

于 2021-03-20T11:16:57.253 回答
0

只有在所有同步代码完成运行后,才会解析 Promise。正如你所说,它可以理解为执行上下文。为了解决 Promise,它需要执行额外的步骤,例如暂停代码的执行。出于这个原因,除非您使用await或回调 ( .catch(() => {...})),否则您将无法按照您想象的方式捕获错误。

您可以在应用程序的顶层等待/回调所有异步进程,并添加一个执行函数的 try catch 块/catch 回调,但如果您使用 REST,则可能必须单独放置捕获。

于 2021-03-20T10:47:42.010 回答