将 Promise.then() 或回调风格的代码迁移为 async/await,核心步骤仅需三步:识别阻塞点、提取 Promise 操作、重构控制流。结合具体工具与工作流程,以下五种实用方法可助你快速完成切换。

一、手动重构:识别 Promise 返回值并用 await 替换 then
若代码中已使用 fetch、axios 等返回 Promise 的函数,手动重构最为直观——逐层将 .then() 链替换为 await,嵌套结构瞬间变为线性顺序。
- 确认函数返回 Promise 实例,例如将
fetch(url).then(...)改写为const res = await fetch(url)。 - 为外层函数添加
async关键字,如function getData()→async function getData()。 - 在每个 Promise 调用前插入
await,例如用const data = await promiseFn()替代promiseFn().then(data => {...})。 - 使用
try/catch包裹await表达式以捕获异常,替换原有的.catch()链。
二、借助 Babel 插件 @babel/plugin-transform-async-to-generator 实现编译时转换
当需要兼容旧版运行时环境时,Babel 插件可在编译阶段自动将 async/await 降级为 generator + Promise 的等效实现,无需改动业务逻辑。
- 安装插件:
npm install --save-dev @babel/plugin-transform-async-to-generator - 在
babel.config.js的 plugins 数组中添加 '@babel/plugin-transform-async-to-generator' - 确保
@babel/preset-env已启用,且 targets 配置覆盖目标环境 - 运行 Babel 编译后,源码中所有 async 函数都会被转译为可执行的 regeneratorRuntime 兼容代码
三、使用 ESLint 插件 eslint-plugin-promise 与辅助规则实现自动提示
此方法不直接改写代码,而是通过静态分析识别可升级为 async/await 的 Promise 链,并在 IDE 中弹出快速修复建议——适合边编码边重构的场景。
- 安装插件:
npm install --save-dev eslint-plugin-promise - 在
.eslintrc.js的 plugins 字段加入 'promise',rules 中启用 'promise/prefer-await-to-then' - 保存文件时,VS Code 或 WebStorm 会在
.then()上显示灯泡图标,点击即可一键转为 await 形式 - 遇到多个
.catch()或复杂链式调用时,插件也会提示将其拆分或封装为独立 async 函数
四、运用 Codemod 工具 jscodeshift 批量重写 Promise 链
大型代码库中若存在大量 .then().catch() 需要统一升级,jscodeshift 是最可靠的选择——基于 AST 解析精准匹配并安全替换,避免正则误匹配。
- 全局安装 jscodeshift:
npm install --global jscodeshift - 下载社区维护的 transform 脚本,例如
transform-then-to-async-await.js - 先用预览命令查看效果:jscodeshift -t transform-then-to-async-await.js src/ --dry --print
- 确认无误后去掉
--dry参数执行实际重写,所有匹配的.then()链都会被替换为await + try/catch结构
五、利用 VS Code 扩展 JavaScript Booster 提供交互式重构
日常开发中更便捷的方式是安装扩展,将光标置于 Promise 链上,按下快捷键即可智能转换,变量名和注释均原样保留,并支持预览差异。
- 在 VS Code 扩展市场搜索并安装 JavaScript Booster
- 打开包含
.then()的 JS 文件,将光标放在任意.then()调用的起始位置 - 按下
Ctrl+Shift+P(Windows/Linux)或Cmd+Shift+P(macOS),输入 Booster: Convert then to async/await - 选择目标作用域(当前行、当前函数或整个文件),扩展会生成对比面板,确认后一键完成转换
