调用异步函数时不使用await是否存在风险?技术咨询
await调用这个异步函数? 好问题!咱们来拆解一下这里面的关键问题,看看直接调用不带await会带来哪些隐患:
1. 未捕获的异步错误会导致进程崩溃
先看你的wierdFunction:里面的setTimeout回调里有个throw new Error('Bang!'),但这个错误根本无法被外层的async函数捕获——因为setTimeout的回调是在独立的宏任务里执行的,当它抛出错误时,外层的async函数早就执行完毕并返回了一个Promise。
当你不带await调用wierdFunction时,它返回的Promise会被直接丢弃,而回调里的错误会变成未捕获的异常。在Node.js环境下,如果没有监听uncaughtException或unhandledRejection事件,这种未捕获的错误会直接导致整个进程崩溃,你的服务就挂了。这绝对是生产环境里要避免的大问题。
2. 完全失去对异步操作的管控能力
现在你说不需要知晓完成时间,但需求是会变的:万一以后你需要记录这个任务的执行日志、在失败时发送告警,或者在任务完成后做一些清理工作?不带await的话,你连这个异步操作的Promise引用都没有,根本没法追踪它的状态,后续扩展会非常麻烦。
3. 代码可读性和维护性的坑
其他开发者看到这段代码时,大概率会疑惑:“为什么这个异步函数没有加await?是忘了写还是故意的?”如果没有明确的注释,很容易造成误解,增加维护成本。而且如果以后wierdFunction被修改成需要返回结果的版本,现在的写法会直接埋下不易察觉的bug。
怎么改进?
如果你确实不需要等待任务完成,但又想避免上述问题,可以捕获这个Promise的错误,不用await但要处理异常:
app.post('/wierd-endpoint', function (req,res){ // 捕获错误,避免进程崩溃,同时明确我们是故意不等待 wierdFunction().catch(err => { console.error('Wierd function encountered an error:', err); // 这里可以加日志、告警等操作 }); res.json({status:"Running. Now, go away."}); });
这样既满足了“无需等待完成”的需求,又避免了未捕获错误的风险,代码也更清晰。
内容的提问来源于stack exchange,提问作者lcssanches

