Generator函数的理解

Generator

  1. 语法上:状态机器,封装了多个内部状态;遍历器对象生成函数
  2. 返回:遍历器对象
    遍历Generator函数内部的每一个状态
  3. 特征
    (1)function*
    (2)内部使用yield
  4. 调用
    调用后并不执行,返回一个指向状态的指针对象(IteratorObject)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function* helloworld () {
    yield 'hello';
    yield 'world';
    return 'ending';
    }

    =>
    执行函数 当前状态值 布尔值
    hw.next() 返回hello done:false //执行第一个yield
    hw.next() world done:false
    hw.next() undefined done:true。//遍历已经结束

可暂停执行的函数,yield为暂停标志

next方法:可有一个参数,作为上个yield的返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function* f() {
for (var i = 0;true;i++){
var reset = yield ;
if (reset) {i = -1 }
}
}
var g = f()
g.next()
g.next()
g.next(true)
=>
value:0 false
value:1 false
value:0 false
next函数中有参数true,可调整函数行为

第一个next()函数传参数无效,用来启动遍历器对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function* foo(x){
var y = 2 * (yield (x+1))
var z = yield(y/3)
return (x+y+z)
}
--->
var a = foo(5)
a.next() //6 ..
a.next() //x,y均无值 NaN ..
a.next() //NaN ..
--->
var b = foo(5)
b.next() //6 done:false:yield的值为5+1=6,返回yield的值为6
b.next(12) //8 done:false 12传递给等待状态的yield(x+1)语句,y=24,所以返回24/3=8
b.next(13) //42 done:true 8赋值给等待状态的yield(y/3),z=13,赋值完成(12+26+4=42)

若需要第一个参数有效,则外包一层

1
2
3
4
5
6
7
8
9
10
11
function wrapper(generatorFunction){
return function(...args){
let generatorObject = generatorFunction(...args)
generatorObject.next()
return generatorObject
}
}
const wrappered = wrapper(function* () {
console.log(`First input:${yield}`)
})
wrappered.next('hello!')

直接迭代集合:for of循环,不用yield

1
2
3
4
5
6
7
8
9
10
11
12
13
function *foo() {
yield 1;
yield 2;
yield 3;
yield 4;
yield 5;
return 6;
}

for (var v of foo()) {
console.log( v );
}
// 1 2 3 4 5

  1. return
    若无return,则返回对象值undefined
  2. return与yield:return无记忆功能,只返回一次
  3. 和Iterator接口关系
    (1)myIterable[Symbol.iterator] = function * () {

}
(2)返回的遍历器对象,有Symbol.iterator属性
执行后返回自身