JavaScript中未await的异步函数在其余代码执行完后是否仍会执行完毕?
长驻进程的传统Web服务场景
你本地测试的异步执行特性完全生效。
只要你的服务是跑在长期不退出的Node.js进程上(比如自建的Express/Koa服务,部署在长期运行的虚拟机、固定容器中),HTTP响应返回不会终止Node.js事件循环。只要进程本身没有崩溃、没有被强制重启,你没有加await调用的func1会正常进入事件循环任务队列,哪怕响应已经发给客户端,内部的数据库写入、日志打印逻辑都会正常执行完成,和你本地测试的输出结果一致。
对应示例代码:
async func1(){ // 等待数据库异步写入 console.log("call finished"); } func2(){ func1(); // 未加await return response.status(200).send(""); } func2();
风险提示:这种写法属于fire-and-forget(发后即忘)模式,一旦func1内部抛出异常,会产生未捕获的Promise rejection,极端情况下会直接导致服务进程退出。如果要用这种写法,必须在func1内部添加catch逻辑处理所有可能的错误。
Serverless云函数/FaaS场景
这个场景下异步逻辑不保证能执行完成,生产环境绝对不要这么写。
所有主流云厂商的云函数运行时,都会在函数向平台返回响应(也就是你调用response.send、或者执行完入口函数return的动作)之后,立刻判定当前请求生命周期结束,马上冻结函数运行容器、暂停CPU调度、清空事件循环待执行任务。这时候还没跑完的func1会被直接中断,内部的数据库调用大概率执行失败,既不会打印后续日志,也无法保证数据正常落库。
少数云厂商提供了专门的后台异步任务、函数预留配置,但这类能力都不是默认开启的,没有显式配置的情况下,不要赌异步代码能在容器冻结前跑完。如果要保证云函数里的逻辑一定执行完成,必须在返回响应之前用await等待所有异步任务执行完毕,再触发响应返回动作。
内容的提问来源于stack exchange,提问作者Exter

