如何对嵌套异步等待使用单个catch函数?

时间:2019-05-21 07:24:20

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

我有此代码:

on('connection', async(socket) => {
  try {
    const promises = members.map(async(member) => {
      try {
        const users = await User.find({})
        const _promises = users.map(async() => {
          try {
            //some code here
          } catch (err) {
            console.log(err)
          }
        })
        await Promise.all(_promises)
      } catch (err) {
        console.log(err)
      }
    })
    await Promise.all(promises)
  } catch (err) {
    console.log(err)
    throw err
  }
})

如您所见,每个嵌套的try函数都有一个catch async。可以对代码进行调整以仅使用单个catch,还是以某种方式简化代码?

2 个答案:

答案 0 :(得分:2)

在处理程序的顶层只能有一个await。如果在其中产生的Promises全部链接在一起,成为最高级别await的Promise(如您的示例中所示),则顶部await将捕获在内部任何地方抛出的错误。

但是,除非catch也处理Promise拒绝,否则您的throw部分应该不是 .on另一个错误,否则,您将得到未处理的Promise拒绝:

on('connection', async(socket) => {
  try {
    const promises = members.map(async(member) => {
      const users = await User.find({})
      const _promises = users.map(async() => {
        //some code here which may throw
      });
      await Promise.all(_promises);
    });
    await Promise.all(promises);
  } catch (err) {
    console.log(err);
  }
})
  • 如果await User.find抛出,则promises数组将包含一个Promise,它会被拒绝,这意味着顶部的await Promise.all(promises);将抛出并被捕获
  • 如果users.map内的东西抛出,_promises将包含拒绝的Promise,因此await Promise.all(_promises);也会抛出。但这位于const promises = members.map回调内部,因此也会导致promises也包含被拒绝的Promise-因此它也将被await Promise.all(promises);捕获。

答案 1 :(得分:0)

如果您调用的函数引发错误,该错误将退回到该函数调用所在的最近的catch块。

try {

   throw "an error";

}
catch(e) {
   console.log(e);   //output: "an error"
}

现在考虑一下

try {

  try {

   throw "an error";

  }
  catch(e) {

    console.log(e);   //output: "an error"

  }

}
catch(e) {
   console.log(e);   //This line is not going to be executed
}

此机制可以将更多错误信息附加到每个级别中生成的错误中。假设您的错误是一个对象,并且每个嵌套的catch bock都将自己的信息附加到错误对象,然后再次抛出该错误对象。

看下面的代码:

尝试{

  try {

   throw {internalError: 101};

  }
  catch(e) {

    //Attach more info and throw again 
    e.additionalInfo = 'Disconnected when gathering information';
    throw e;

  }

}
catch(e) {
   e.message = 'Cannot get information'
   console.log(e);   //Final error with lot of information
}