使用for...of循环时,如何向生成器函数传递返回值?
如何在迭代生成器时向生成器传递值
首先要明确:for...of循环本身无法直接向生成器传递值,因为它在迭代过程中会自动调用generator.next(),且每次调用都不带参数。要实现向生成器传递值,我们需要手动控制生成器的迭代过程,调用next()时传入参数;如果是异步场景(比如你的代码里用到了Promise),则可以结合async/await处理异步操作的同时完成传值。
一、核心原理:生成器的next()传参机制
生成器的next(arg)方法接收的参数arg,会作为上一个yield表达式的返回值。注意:第一次调用next()时传入的参数会被忽略,因为此时生成器还没有执行到任何yield语句,没有等待返回值的表达式。
二、适配你的异步场景的实现方案
你的代码里生成器yield了Promise,我们可以封装一个异步迭代函数,手动调用next()并传递计数器值,同时用async/await处理异步操作:
function generate(time, id) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(`ALERT: ${id}`) resolve(`${id} success.`) }, time) }) } function* generator() { let internalCounter = 0; // 这里设置迭代次数,也可以改成无限循环直到外部终止 while (internalCounter < 3) { // 接收外部传入的计数器值,作为上一个yield的返回值 const receivedCounter = yield generate(3000, `Task-${internalCounter}`); if (receivedCounter !== undefined) { console.log(`生成器收到外部传递的计数器值:${receivedCounter}`); // 用外部传入的值更新内部计数器 internalCounter = receivedCounter; } internalCounter++; } } // 封装异步迭代+传值的逻辑 async function iterateWithCounter() { const gen = generator(); let nextResult = gen.next(); // 第一次调用启动生成器,参数会被忽略 let externalCounter = 0; while (!nextResult.done) { // 等待当前yield的Promise完成 const taskResult = await nextResult.value; console.log(taskResult); // 递增外部计数器,传递给生成器 externalCounter++; nextResult = gen.next(externalCounter); } } // 执行迭代 iterateWithCounter();
运行结果(按时间顺序)
ALERT: Task-0 Task-0 success. 生成器收到外部传递的计数器值:1 ALERT: Task-1 Task-1 success. 生成器收到外部传递的计数器值:2 ALERT: Task-2 Task-2 success. 生成器收到外部传递的计数器值:3
三、同步场景的简化示例
如果不需要处理异步,普通生成器的传值逻辑会更简洁:
function* syncGenerator() { let count = 0; while (true) { const received = yield count; if (received) { console.log(`生成器收到:${received}`); count = received; } count++; } } const gen = syncGenerator(); // 启动生成器 console.log(`生成器输出:${gen.next().value}`); // 0 // 手动传参迭代 for (let i = 1; i <= 3; i++) { console.log(`生成器输出:${gen.next(i).value}`); }
运行结果
生成器输出:0 生成器收到:1 生成器输出:2 生成器收到:2 生成器输出:3 生成器收到:3 生成器输出:4
内容的提问来源于stack exchange,提问作者Cazineer
相关产品推荐
相关产品推荐

