javascript通过迭代器对象控制生成器

调用生成器函数不一定会执行生成器函数体。通过创建迭代器对象,可以与生成器通信。例如,可以通过迭代器对象请求满足条件的值。

console.log('-----------------通过迭代器对象控制生成器----------------');
//定义一个生成器,它能生成一个包含两个weapon的序列
function* WeaponGenerator() {
  yield 'Katana';
  yield 'Wakizashi';
}

//调用生成器得到一个迭代器,从而我们能够控制生成器的执行
const weaponsInterator = WeaponGenerator();

//调用迭代器的next方法向生成器请求一个新值
const result1 = weaponsInterator.next();

//结果为一个对象,其中包含着一个返回值,及一个指示器告诉我们生成器是否还会生成值
if (typeof result1 === 'object' && result1.value === 'Katana' && !result1.done) {
  console.log("Katana received!");
}

//再次调用next方法从生成器中获取新值
const result2 = weaponsInterator.next();
if (typeof result2 === 'object' && result2.value === 'Wakizashi' && !result2.done) {
  console.log('Wakizashi received!');
}

//当没有可执行的代码,生成器就会返回'undefined'值,表示它的状态已经完成
const result3 = weaponsInterator.next();
if (typeof result3 === 'object' && result3.value === undefined && result3.done) {
  console.log('There are no more results!');
}

 

调用生成器后,就会创建一个迭代器(iterator):

const weaponsInterator = WeaponGenerator();

迭代器用于控制生成器的执行。迭代器对象暴露的最基本接口是next方法。这个方法可以用来向生成器请求一个值,从而控制生成器:

const result1 = weaponsInterator.next();

next函数调用后,生成器就开始执行代码,当代码执行到yield关键字时,就会生成一个中间结果(生成值序列中的一项),然后返回一个新对象,其中封装了结果值和指示完成的指示器。

每当生成一个当前值后,生成器就会非阻塞地挂起执行,随后耐心等待下一次值请求的到达。这是普通函数完全不具有的强大特性,后续的例子中它还会起到更大的作用。

在上述代码中,第一次调用生成器的next方法让生成器代码执行到第一个yield表达式(yield 'Katana'),然后返回一个对象。该对象的value的值置为Katana,属性done的值置为false,表明之后还会有值生成。

随后,通过再次调用WeaponGenerator的next方法,再次向生成器请求另一个值:

const result2 = weaponsInterator.next();

该操作将生成器从挂起状态唤醒,中断执行的生成器从上次离开的位置继续执行代码,直到再次遇到另一个中间值:yield 'Wakizashi'。随即生成看一个包含着值Wakizashi的对象,生成器挂起。

最后,当第三次执行next方法后,生成器恢复执行。但这一次,没有更多可供它执行的代码了,所以生成器返回一个结果对象,属性value被置为undefined,属性done被置为true,表明它的工作已经完成了。

 

参考《JavaScript忍者秘籍》

猜你喜欢

转载自blog.csdn.net/zhangying1994/article/details/85459803