未使用await的异步函数是否可以安全移除async关键字?
无await场景下async标识移除可行性分析
你给出的代码是一个async立即执行函数表达式(IIFE):
(async function(){ 'use strict'; const {appLogger, monitorLogger} = require('./functions/logger'); ... for (let i in p) { p[i].Filename = i; check(p[i]); } ... app.get('/example.json', (req, res) => { res.send(JSON.stringify(checkStates, null, 4)); }) app.listen(port, () => { appLogger.info(`Exposing http://localhost:${port}/example.json`); }) })();
只要排查确认不存在下文提到的特殊依赖场景,移除async标识是完全安全的;但因为是线上代码,建议先完成几个核心点的校验再操作,避免触发意料之外的问题。
async标识的隐性影响
即使函数内部没有用到await,async标识也会带来两个默认的行为变化:
- 函数返回值永远会被封装为Promise类型。如果这个IIFE的返回值没有被任何代码接收、调用
.then()/.catch()处理,这层特性不会影响现有逻辑。 - 错误处理行为存在差异:如果函数内部抛出同步错误,普通函数会直接抛出同步异常,没有被try/catch捕获的话会直接导致进程崩溃;而async函数内部的同步错误会被封装为rejected状态的Promise,没有被.catch()处理的话只会触发
unhandledRejection事件,和同步抛错的处理链路完全不同。如果你的线上服务对这两类异常的处理策略不一致(比如unhandledRejection配置为只打日志不退出,同步异常直接退出),移除async就会改变错误发生时的服务行为。
移除前必须完成的排查项
- 排查该IIFE的返回值是否被使用:确认有没有代码接收这个立即执行函数的返回值,比如
const result = (async function(){...})()这种写法,如果有且后续对result做了Promise相关操作,移除async会直接报语法错误。 - 完整检查函数内所有省略的代码:确认省略部分确实没有用到await关键字,没有依赖async函数的语法特性。
- 对齐异常处理逻辑:确认现有代码中该函数内部的抛错场景,两种异常处理模式下的业务表现一致,不会因为异常类型变化引发线上故障。
操作建议
- 如果排查后所有依赖都没有问题,可以直接移除async标识,不会有额外副作用。
- 如果不敢完全确认所有逻辑,保留async标识也几乎不会带来性能损耗,只是多了一层无意义的Promise包装,对业务运行没有影响,可以选择保留避免风险。
内容的提问来源于stack exchange,提问作者Sandra Schlichting
相关产品推荐
相关产品推荐

