generator函数首次调用next()传参无效,后续next(value)的value会作为上一个yield表达式的返回值;javascript中next(value)等价于python的send(),可用于异步流程控制。

Generator 函数本身不直接“接收参数”来启动执行,但它的 第一次调用 next() 可以传参,这个参数会被忽略(规范规定首次传参无效);真正能被外部传入并影响内部逻辑的,是 后续调用 next(value) 时传入的 value —— 它会作为上一个 yield 表达式的返回值,进入函数体继续执行。
next() 的参数如何成为 yield 的返回值
每次调用 gen.next(value) 时:
- 如果这是第一次调用,
value会被丢弃(即使传了也没用);执行从函数开头开始,直到遇到第一个yield,暂停并返回该表达式的值。 - 如果是第二次及之后的调用,
value会变成 上一个yield表达式所在行的返回值。
例如:
function* counter() {let step = yield 1;
console.log('收到:', step); // 第二次 next(10) 传入的 10 在这里被接收
yield 2 + step;
}
运行:
const gen = counter();gen.next(); // { value: 1, done: false } → 暂停在 yield 1 处
gen.next(10); // { value: 12, done: false } → step = 10,yield 2 + step 返回 12
用 send() 模拟(注意:JavaScript 没有原生 send 方法)
Python 的 Generator 有 send(),JS 中没有同名方法,但 next(value) 就是等价功能。只要不是第一次调用,它就承担“发送数据”的角色。可封装一个语义更清晰的辅助函数:
return gen.next(value);
}
这样写更接近直觉:
send(gen, 'hello'); // 相当于 gen.next('hello')
配合异步流程控制接收参数
Generator 常用于协程式异步(如早期 co 库或手写 runner)。此时外部通过 next() 把异步结果“注入”进去:
const id = yield Promise.resolve(123); // 模拟异步获取 id
const user = yield fetch(`/api/users/${id}`);
return user;
}
手动驱动时:
const gen = fetchUser();gen.next().value.then(id => {
gen.next(id).value.then(user => {
console.log(user);
});
});
这里 id 就是外部“传入”给第二个 yield 的值,由 gen.next(id) 注入。
注意事项与常见误区
- 首次
next()传参永远无效,不要依赖它初始化状态 —— 初始值应在 Generator 内部定义或通过闭包/参数传入函数本身。 -
yield是表达式,有返回值;而yield*会委托给另一个迭代器,并把传入的next(value)转发给它。 - 如果 Generator 已经
done: true,再调用next(value)仍会返回{ value: undefined, done: true },传入的value不起作用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











