【问题标题】:Confusion around 'nested' try/catch statements in Javascript围绕 Javascript 中的“嵌套”try/catch 语句感到困惑
【发布时间】:2020-08-01 22:17:04
【问题描述】:

基本上我有一个包含 try/catch 的异步函数,该函数调用另一个也包含 try catch 的异步函数,我对如何正确实现我正在做的事情有点困惑。一些“伪代码”显示了我当前的实现:

const main = async () => {
  try {
    const test = await secondFunc();
    console.log(test);

  } catch(err) {

    console.log('Found an error!');
    console.log(err);
  }

const secondFunc = async () => {
  try {
    await performSomeRequestExample();

  } catch(err) {
    if (err.x === 'x') {
      doSomething();
    } else {

      //********
      throw err;
      //********
  }

}

所以我要做的是让throw(err)(被星号包围)被main()中的catch捕获,这也将调用console.log('Found an error!'),但目前发生的是从secondFunc() 抛出错误,main() 中的catch 永远不会被命中,我得到一个未处理的承诺拒绝。

关于我做错了什么的任何指导?

【问题讨论】:

  • 你的 else 有没有到达过?如果您在第二个函数中的 await 前面放置一个变量,还有什么变化吗?

标签: javascript node.js error-handling async-await try-catch


【解决方案1】:

我的建议是尽量减少使用 try/catch,除非绝对必要。使用async 函数(或任何返回Promise 对象的函数),您通常可以通过不必担心try/catch 块来简化事情,除非您需要针对某些错误执行特定操作。您还可以使用 .catch 而不是 try/catch 块来使内容更易于阅读。

例如你上面的代码可以这样写:

const main = async () => {
  const test = await secondFunc().catch(err => {
    console.log("Found an error from secondFunc!", err);
    throw err;  // if you want to send it along to main's caller
  });
  if (test) {
    console.log("Test", test);
  }
};

const secondFunc = () => {
  return performSomeRequestExample().catch(err => {
    if (err.x === "x") {
      doSomething();
    } else {
      throw err;
    }
  });
};

const performSomeRequestExample = () => Promise.reject("bad");

main().then(
  () => console.log("worked"),
  err => console.log("failed from main", err)
);

secondFunc 中,我们不需要使用async,因为我们可以只返回从performSomeRequestExample 返回的承诺并处理.catch 中的任何失败。

【讨论】:

  • 不要假设他不需要第二个函数是异步的,因为你知道 performSomeRequestExample() 是一个获取并且需要等待并且在该OP的代码之上是不完整的并且不反映他们真正拥有的东西。
  • 是的。如果 performSomeRequestExample 没有返回 Promise,那么您可以将其设为异步或返回解析为其返回值的 Promise
【解决方案2】:

你应该使用

const secondFunc = async () => {
  performSomeRequestExample().then(res =>{
    console.log(res);
  })
  .catch(err => {
    console.log(err);
  }
)

【讨论】:

    【解决方案3】:

    在 performSomeRequestExample 的 await 之前添加一个 return。

    const secondFunc = async () => {
        try {
            return await performSomeRequestExample();
        } catch (err) {
            if (err.x === 'x') {
                console.log('x');
            } else {
                throw err;
            }
        }
    }
    

    或者你也可以在 awaited 函数之后使用 .catch()。

    【讨论】:

      【解决方案4】:

      另一种解决方案可以是这样的

      const main =  async() => {
      try {
          const test = await secondFunc();
          console.log(test);
      
        } catch(err) {
      
          console.log('Found an error!');
          console.log(err);
        }
      }
      
      const secondFunc = async () => {
        //return await performSomeRequestExample();  //for success
        return await performSomeRequestExample(2); //for error
      }
      
      const performSomeRequestExample = async(abc=1) => {
        return new Promise(function(resolve,reject){
          if(abc ==1){
            setInterval(resolve("yes"),400);
          }else{
            setInterval(reject("opps"),400);
          }
        });
      }
      
      
      main();
      

      在此链接测试此代码: https://repl.it/repls/JoyfulSomberTelevision

      【讨论】:

        猜你喜欢
        • 2011-02-04
        • 2020-06-15
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多