Generator函数适合渐进收编遗留异步逻辑,以yield封装异步操作与条件判断,解耦业务逻辑与流程控制;配合轻量执行器可统一调度多分支、并行请求及错误处理,无需顶层改造,兼容旧环境。

Generator 函数适合在不重写整个异步链的前提下,逐步收编遗留系统中散乱的回调、Promise.then 嵌套或状态判断逻辑。它不依赖顶层 async/await 改造,能以最小侵入方式统一调度多分支流程。
识别可提取的异步决策点
遗留代码中常见类似“根据接口返回 status 走不同处理路径”“按用户角色加载不同模块”“失败时降级调用备用接口”的分支逻辑。这些正是 Generator 的天然适用场景——每个 yield 可封装一个异步动作 + 条件判断,把“执行哪条路”从嵌套结构里解放出来。
- 把 if/else 或 switch 中的异步调用(如 fetch、localStorage.getItem、第三方 SDK 回调)抽成独立 yield 表达式
- 将错误处理(如 .catch 或 try/catch 内的 retry/switchFallback)转为 yield 后接 next(value) 或 throw(error) 控制流向
- 避免在 generator 内部写复杂条件;只 yield 纯异步操作,把分支逻辑交给执行器或外层包装函数判断
用 yield 返回上下文数据,而非硬编码分支
Generator 不直接做 if (res.status === 200),而是 yield 一个 Promise,让执行器拿到结果后再决定下一步调用 next(data) 还是 throw(err)。这样业务逻辑和流程控制解耦,后续替换执行器或加日志、重试策略更方便。
- 示例:yield api.getUser(id) → 执行器收到 { data, status } 后,根据 status 决定 next({ user }) 还是 throw(new Error('not found'))
- 多个并行请求可用 yield Promise.all([p1, p2]),保持单线程语义,避免 race condition
- 需要动态分支时,yield 一个对象如 { type: 'role_check', payload: userId },由执行器查表映射到对应 handler
搭配轻量执行器,兼容旧环境
不用引入 co 或 full-fledged 流程库。写一个 20 行左右的 runGenerator 函数即可启动 generator 并自动处理 Promise、传递结果、捕获异常。它可复用在所有 legacy 模块中,无需修改原有构建配置或 polyfill。
- 执行器核心逻辑:调用 next() → 检查 value 是否为 Promise → 是则 .then(res => next(res)) / .catch(err => throw(err))
- 对老项目中仍用 callback 的 API,用 Promise 包一层:yield new Promise(r => oldApi(..., r))
- 执行器可注入 logger、traceId、timeout 等横切能力,所有 generator 自动受益
渐进迁移:从单个函数开始,不碰主流程
不要一上来就重构整个页面初始化逻辑。选一个高维护成本、分支多、调试困难的独立模块(比如登录后的权限校验+首页资源加载组合逻辑),用 function* 替换其内部回调链。原有调用方仍传 callback 或监听事件,只内部实现变 generator。
- 保留原有函数签名,内部 return runGenerator(myGen(...)),对外完全无感
- 测试时对比新旧行为是否一致,尤其关注 error case 和 loading 状态变化时机
- 上线后通过执行器统一埋点,观察各 yield 步骤耗时与失败率,为后续优化提供依据










