我可以在使用 await 的异步函数中使用 Promise.prototype.catch 吗?

Can I use Promise.prototype.catch inside async functions that is using await?

在使用 await 的异步函数内部使用 Promise.prototype.catch 是否有任何影响?

例如:

async funciton sendMessage(topic, bodyObj) {
  // implementation is not important
}

async function removeFromInventory(item, amount) {
  const storeData = await getSoreData(item)
  const removeResult = await inventory.removeFromStore(storeData.id, item.id, amount)
  sendMessage(
    Message.REMOVE_INVENTORY_SUCCESS, removeResult
  ).catch(log.error) // <== here, is it has downside and it is better to use try/catch?
  return removeResult
}

我不想 await 等待 sendMessage 完成,我使用 .catch 来处理拒绝,换句话说就是避免未处理的拒绝。

Are there any implications of using Promise.prototype.catch inside of async functions where await is used?

你使用它的方式,主要的含义是你正在“吞噬”错误。您记录错误然后继续,就好像没有错误一样。如果这是设计意图,它会工作得很好。


至于一般主题,您可以将 async/await.then().catch() 混合使用。它会起作用 - 没有针对它的语言禁令。

也就是说,通常不建议混合使用它们,因为它会产生更多令人困惑的代码,如果错误处理 and/or 错误传播得到一致且正确的实施并不完全清楚,因为您混合使用两种不同的错误处理模型。

我倾向于将 async/await.catch() 混合使用的唯一一次是我想记录并“吃掉”一个错误,同时让其他一切继续进行,就好像没有错误一样。

例如,当删除函数内的临时文件时经常会发生这种情况,否则会使用 async/await:

  fs.promises.unlink(tempFile).catch(err => console.log(err));

我这样做只是因为用 try/catch 包围它更紧凑而且我正在“吞噬”错误,因为如果失败并且主要操作已经完成,则没有任何用处可做成功地。我也可能不会放置 await,因为我实际上不需要主操作来等待此清理完成,然后再返回其完成信息。

为了比较,另一种方法是:

  try {
      await fs.promises.unlink(tempFile);
  } catch(e) {
      console.log(e);
  }

所以,如果这是您对 sendMessage(...).catch() 的意图,那么这完全没问题。这将记录错误,否则“吃掉”错误,因此处理将继续,就好像没有错误一样。

另一方面,如果您希望该错误传播回调用者,那么这根本不是您想要的,因为那不会发生。此代码处理错误并将其隐藏起来,以免传播回调用者。