生成器

106 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

大家好!我是前端爬楼工程师🚹,一个野生程序员。好奇新技术,仰慕牛大佬。如果喜欢我的文章,可以关注➕点赞,为我注入能量,与我一同成长吧~

生成器和普通函数的区别就是函数名前面多了个*, 其次就是yield关键字。

迭代器的消息传递

生成器调用会构建一个迭代器,例如下面的it.

function *foo(x){
    var y = x * (yield)
    return y
}
var it = foo(6) 
var res = it.next() // 启动
res.value  //undefined 因为yield 后面没有值
res = it.next(7)
res.value // 42

function *foo(x){
    var y = x * (yield 10)
    return y
}
var it = foo(6)
var res = it.next()
res.value  // 这里的是10 
res = it.next(7)
res.value // 也是42
  • 我们调用foo的时候,传入的6,所以此时x = 6, 虽然我们调用了foo,此时foo的代码还未执行
  • 需要it.next()才能触发真正的执行,此时代码就会运行到var y = x * yield ,遇到了yield, 代码会再次暂停,
  • 此时it.next(7)next传入的值就代表了yield的返回值,无论yield后面跟随了什么值,都以next()传入的为准,此时yield变为7,最后y就算出来得到42
  • 第一个yield如果后面跟着参数,那它应是第一个it.next()value值。

第一个next是启动生成器,并运行到一个yield处, 第二个next调用后完成第一个被暂停的yield表达式,第三个next调用后完成第二个yield,以此类推.

以上就是迭代器的消息传递。yieldnext建立双向的消息传递。

多个迭代器

迭代器是生成器的构建的一个实例,一个生成器可以有多个迭代器,多个迭代器可以同时运行,彼此可以交互。

function *foo(){
    var x = yield 2;
    z++
    var y = yield(x * z)
    console.log(x, y ,z)
}
var z= 1

// it1 和 it2 是两个不同的迭代器
var it1 = foo()
var it2 = foo() 
// next接收到第一个yield 返回值为2
var val1 = it1.next().value // 2 
var val2 = it2.next().value // 2
// it1 next传入 20  it2 next传入 200
val1 = it1.next(val2 * 10).value // 40  x:20 y undefined z:2
val2 = it2.next(val1 * 5).value // 600  x:200 y undefined z:3
it1.next(val2/3) // y:300   // 20 300 3
it2.next(val1/4) // y:10  // 200 10 3

通过之前迭代器通信的例子我们可以知道上面的结果并不难。