yield本身不处理异步,仅暂停生成器并交出控制权;真正实现异步暂停的是yield后接Promise并配合await或手动next()调度;async function*使yield可等待Promise settle后再产出值。

yield 本身不处理异步,它只是暂停生成器函数的执行,并交出控制权;真正实现“异步迭代中状态暂停”的,是 yield 后接 Promise + 配合 await 或 next() 的手动调度。
yield 不会自动等待异步操作完成
在生成器函数中写 yield fetch('/api/data'),并不会等请求返回再继续。它只是把创建好的 Promise 对象立刻 yield 出去,然后暂停。后续是否等待、如何等待,由调用方(比如 for-await-of 或手动调用 next())决定。
- 直接调用
gen.next()返回的是{ value: Promise, done: false },Promise 还处于 pending 状态 - 若想等请求完成,需在外部
await value,或用async function*(异步生成器)配合await yield
异步生成器(async function*)让 yield 真正“等”异步结果
使用 async function* 声明生成器后,内部可用 await yield,此时 yield 表达式会等待右侧 Promise settle 后再产出值:
async function* asyncCounter() {
for (let i = 1; i setTimeout(r, 1000)); // 模拟异步延迟
yield i; // 这里的 yield 会等上面的 await 完成后再执行
}
}
这时用 for await (const val of asyncCounter()) 就能按秒依次拿到 1、2、3 —— 暂停点由 await 控制,yield 负责产出。
手动调度 next() 时,暂停状态由你掌控
生成器对象的 next() 方法本身是同步的,但你可以选择何时调用它、是否 await 其 value:
- 同步调用
it.next()→ 得到 {value: Promise, done: false},不暂停异步过程 - 写成
const res = await it.next(); await res.value;→ 显式等待异步结果,实现可控暂停 - 搭配
Promise.all([...])可并发拉取多个异步项,再统一 yield,适合批量预加载场景
for-await-of 是最自然的消费方式
只要生成器是 async function*,且每个 yield 后都经过 await(或 yield 的是已 resolve 的 Promise),for await 就会自动等待每次 yield 完成后再进入下一轮循环:
async function* fetchUsers() {
const ids = [1, 2, 3];
for (const id of ids) {
const user = await fetch(`/user/${id}`).then(r => r.json());
yield user; // 每次 yield 前都等到了 user 数据
}
}
<p>// 使用时:
for await (const user of fetchUsers()) {
console.log(user); // 依次打印,每条间隔由 fetch 决定
}</p>
这种写法隐藏了手动调用 next 和 await 的细节,让异步迭代看起来像同步遍历,但底层仍是基于 yield 的暂停/恢复机制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











