前端JavaScript基础训练系列一百八十一:生产者与迭代器

在告诉你结果之前,你能推断出前面的程序运行后 a 和 b 的值吗?不要作弊!

console.log( a, b ); // 12 18
s2();
console.log( a, b );
// 11 22

最后的结果是 11 和 22,和的版本一样。现在交替执行顺序,看看 a 和 b 的值是

作为留给大家的练习,请试着重新安排 s1() 和 s2() 的调用顺序,看看还能 够得到多少种结果组合。不要忘了,你总是需要 3 次 s1() 调用和 4 次 s2() 调用。回忆一下前面关于 next() 和 yield 匹配的讨论,想想为什么。
当然,你基本不可能故意创建让人迷惑到这种程度的交替运行实际代码,因为这给理解代 码带来了极大的难度。但这个练习很有趣,对于理解多个生成器如何在共享的作用域上并 发运行也有指导意义,因为这个功能有很多用武之地。

生成器产生值

在前面一节中,我们提到生成器的一种有趣用法是作为一种产生值的方式。这 的重点,但是如果不介绍一些基础的话,就会缺乏完整性了,特别是因为这正是“生成 器”这个名称最初的使用场景。
下面要偏一下题,先介绍一点迭代器,不过我们还会回来介绍它们与生成器的关系以及如 何使用生成器来生成值。

生产者与迭代器

假定你要产生一系列值,其中每个值都与前面一个有特定的关系。要实现这一点,需要一
个有状态的生产者能够记住其生成的最后一个值。
可以实现一个直接使用函数闭包的版本(参见本系列的《你不知道的 JavaScript(上卷)》 的“作用域和闭包”部分),类似如下:

    var gimmeSomething = (function(){
         var nextVal;
         return function(){
             if (nextVal === undefined) {
nextVal = 1; }
             else {
                 nextVal = (3 * nextVal) +6;
  }
        return nextVal;
    };
})();
gimmeSomething();
gimmeSomething();
gimmeSomething();
gimmeSomething();
// 1
// 9
// 33
// 105

这里 nextVal 的计算逻辑已经简化了,但是从概念上说,我们希望直到下一 次 gimmeSomething() 调用发生时才计算下一个值(即 nextVal)。否则,一 般来说,对更持久化或比起简单数字资源更受限的生产者来说,这可能就是 资源泄漏的设计。
生成任意数字序列并不是一个很实际的例子。但如果是想要从数据源生成记录呢?可以采 用基本相同的代码。
实际上,这个任务是一个非常通用的设计模式,通常通过迭代器来解决。迭代器是一个定 义良好的接口,用于从一个生产者一步步得到一系列值。JavaScript 迭代器的接口,与多 数语言类似,就是每次想要从生产者得到下一个值的时候调用 next()。
可以为我们的数字序列生成器实现标准的迭代器接口:

var something = (function(){
var nextVal;
return {
// for..of循环需要
[Symbol.iterator]: function(){ return this; },
// 标准迭代器接口方法 next: function(){
                 if (nextVal === undefined) {
                     nextVal = 1;
}
else {
                     nextVal = (3 * nextVal) + 6;
                 }
                 return { done:false, value:nextVal };
             }
 }; })();
something.next().value;
something.next().value;
something.next().value;
something.next().value;
// 1
// 9
// 33
// 105
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值