生成器函数配合闭包可构建轻量、可复用、状态隔离的异步控制流管理器,其核心是function*暂停执行+闭包保存上下文+外部驱动next/resume实现手动调度。

生成器函数配合闭包,能构建轻量、可复用、状态隔离的异步控制流管理器——它不依赖 Promise 库或运行时,而是靠 function* 暂停执行 + 闭包保存上下文 + 外部驱动逻辑来实现“手动调度”的异步流程。
核心思路:用闭包封装执行状态与恢复逻辑
生成器本身不执行异步操作,它只定义步骤和暂停点;真正让 yield 后接异步任务、并自动 resume 的,是闭包捕获的迭代器和调度函数。闭包确保每次调用管理器都拥有独立的状态(比如当前 pending 的 Promise、错误处理器、重试计数等),避免全局污染。
- 闭包保存:
iterator实例、onError回调、retryCount等私有状态 - 生成器产出:
Promise或带then/catch方法的对象(即“可等待值”) - 管理器驱动:
next()→ 获取 yield 出的 Promise →.then(res => it.next(res))→ 自动推进
基础实现:一个支持错误捕获的 runGenerator
下面是一个最小可用的闭包式管理器,它接收生成器函数和初始参数,返回一个可启动的执行器:
function createAsyncRunner(genFn, ...initArgs) {
return function() {
const iterator = genFn(...initArgs);
<pre class="brush:php;toolbar:false;">function handleNext(result) {
const { value, done } = iterator.next(result);
if (done) return value;
// 假设 value 是 Promise;也可扩展支持 thenable 或自定义 awaitable 对象
return Promise.resolve(value)
.then(data => handleNext(data))
.catch(err => {
// 尝试向生成器注入错误(需生成器内部有 try/catch)
const { value: errValue, done: errDone } = iterator.throw?.(err) || {};
if (errDone) return errValue;
return handleNext(errValue);
});
}
return handleNext();
}; }
使用示例:
function* fetchDataFlow() {
try {
const user = yield fetch('/api/user');
const json = yield user.json();
const posts = yield fetch(`/api/posts?uid=${json.id}`);
return yield posts.json();
} catch (e) {
console.warn('流程中断:', e.message);
return null;
}
}
<p>const run = createAsyncRunner(fetchDataFlow);
run().then(console.log); // 自动串行执行所有 yield 步骤</p>
进阶能力:通过闭包添加重试、超时、上下文透传
在闭包内可轻松注入策略逻辑,例如:
-
重试机制:闭包持有
retry = 3和attempt = 0,每次yield失败时递增并重新调用it.next() -
超时包装:对每个 yield 值自动套一层
Promise.race([value, timeout(5000)]),超时则 throw -
上下文透传:闭包中维护一个
ctx = { auth: token, traceId: uuid() },每次next(ctx)把上下文向下传递
关键在于——这些逻辑都封装在闭包作用域里,不影响生成器函数本身,也不污染外部环境。
注意事项:生成器需配合 yield 规范设计
要让管理器稳定工作,生成器函数需遵守几点约定:
- 每个
yield后面尽量是 Promise 或 thenable,避免原始值干扰调度链 - 如需处理非 Promise 值(如立即返回的配置),管理器应先
Promise.resolve(value)统一处理 - 错误处理推荐用
iterator.throw(err)而非仅靠外部 catch,这样能精准落入生成器内的try/catch - 避免在生成器内直接
return异步结果;最终值应由return语句同步返回,由管理器统一 resolve










