在使用await的async函数中能否使用Promise.prototype.catch?
async 函数中非等待 Promise 使用 catch 方法的影响分析
写法合理性说明
你当前的写法是符合需求的:你不需要等待sendMessage执行完成就返回结果,直接给返回的 Promise 追加.catch(log.error)确实可以避免触发未处理的 Promise 拒绝警告,这一步的作用是完全生效的。
潜在弊端
这种写法没有功能性的致命问题,但存在几个维护层面的小缺陷:
- 错误处理逻辑和主业务逻辑割裂,后续如果需要针对
sendMessage的错误增加除打日志外的操作(比如监控上报、局部容错补偿),游离的catch回调不好和函数内其他错误处理逻辑整合,维护成本更高。 - 如果
log.error本身执行时抛出错误,这个二级错误依旧会成为未处理的 Promise 拒绝,没有额外的兜底捕获机制。 - 语义不够明确,其他维护者看到无
await的异步调用时,可能会误以为是漏写了await,需要额外花时间理解你是故意不等待执行的设计。
和 try/catch 的对比
首先要明确:如果你不打算等待sendMessage执行完成,直接用外层的 try/catch 包裹sendMessage调用是完全没用的。因为 try/catch 只能捕获当前同步执行的错误、以及await的 Promise 的拒绝状态,不添加await的话,sendMessage的异步错误不会被外层 try/catch 捕获。
如果要改用 try/catch 实现同等效果,你需要把调用包在独立的自执行 async 函数中:
async function removeFromInventory(item, amount) { const storeData = await getStoreData(item) const removeResult = await inventory.removeFromStore(storeData.id, item.id, amount) // 独立自执行异步块,不阻塞外层函数返回 ;(async () => { try { await sendMessage(Message.REMOVE_INVENTORY_SUCCESS, removeResult) } catch (err) { log.error(err) } })() return removeResult }
这种写法和你直接用.catch的方案功能、性能完全一致,只是代码风格的差异,不存在孰优孰劣。
选择建议
- 如果你的需求仅为记录
sendMessage的错误日志,没有额外扩展需求,且团队对这种写法有共识,现有.catch的写法完全可以使用,没有本质缺陷。 - 如果团队统一要求用 try/catch 处理所有异步错误,或者后续有扩展错误处理逻辑的规划,建议改用自执行 async 函数+内部 try/catch 的写法,更符合统一的编码规范。
补充:你提供的示例代码中
async funciton sendMessage为拼写错误,正确写法为async function sendMessage,getSoreData应为getStoreData。
内容的提问来源于stack exchange,提问作者Dmitry Shvetsov
相关产品推荐
相关产品推荐

