使用方法如下: 

function* WeaponGenerator() {                 // 通过在关键字 function 后面添加星号 * 定义生成器函数
 yield "Katana";                              // 使用新的关键字 yield 生成独立的值
 yield "Wakizashi"; 
 yield "Kusarigama"; 
} 
for (let weapon of WeaponGenerator()) { assert(weapon !== undefined, weapon); }
(for-of 循环是对迭代器进行迭代的语法糖)
 
对初学者来说,调用生成器并不会执行生成器函数,相反,它会创建一个叫作迭代器(iterator)的对象: 

 

 

 

迭代器用于控制生成器的执行。迭代器对象暴露的最基本接口是 next 方法。这个方法可以用来向生成器请求一个值,从而控制生成器:
const result1 = weaponsIterator.next();
next 函数调用后,生成器就开始执行代码,当代码执行到 yield 关键字时,就会生成一个中间结果(生成值序列中的一项),然后返回一个新对象,其中封装了结果值和一个指示完成的指示器。
每当生成一个当前值后,生成器就会非阻塞地挂起执行,随后耐心等待下一次值请求的到达。

 

把执行权交给下一个生成器

正如在标准函数中调用另一个标准函数,我们需要把生成器的执行委托给另一个生成器。

 

function* WarriorGenerator(){ 
 yield "Sun Tzu"; 
 yield* NinjaGenerator();                                 // yield*将执行权交给了另一个生成器
 yield "Genghis Khan"; 
} 
function* NinjaGenerator(){ 
 yield "Hattori"; 
 yield "Yoshi"; 
} 
for(let warrior of WarriorGenerator()){ 
 assert(warrior !== null, warrior);                        //  Sun Tzu、Hattori、Yoshi、Genghis Khan
}

 

作为生成器函数参数发送值

function* NinjaGenerator(action) { 
 const imposter = yield ("Hattori " + action); 
 assert(imposter === "Hanzo", "The generator has been infiltrated"); 
 yield ("Yoshi (" + imposter + ") " + action); 
} 
const ninjaIterator = NinjaGenerator("skulk"); 
const result1 = ninjaIterator.next(); 
assert(result1.value === "Hattori skulk","Hattori is skulking"); 
const result2 = ninjaIterator.next("Hanzo"); 
assert(result2.value === "Yoshi (Hanzo) skulk",  "We have an imposter!");
第二次调用 ninjaIterator 的 next 方法则发生了有趣的事:ninjaIterator.next("Hanzo")。这一次,我们使用 next 方法将计算得到的值又传递回生成器。生成器函数耐心地等待着,在表达式 yield ("Hattori " + action)位置挂起,故而值 Hanzo 作为参数传入了 next()方法,并用作整个 yield 表达式的值。本例中,也就是表示语句 imposter = yield("Hattori " + action) 中的变量 imposter 会以值 Hanzo 作为结尾。

 

 

 

posted on 2022-01-18 17:23  occc  阅读(150)  评论(0编辑  收藏  举报