Generator
常规函数只会返回一个单一值(或者不返回任何值)。
而Generator可以按需一个接一个地返回(“yield”)多个值。它们可与iterable完美配合使用,从而可以轻松创建数据流。
Generator 函数
要创建一个generator,我们需要一个特殊的语法结构:function*
,即所谓地“generator function”。
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
Generator函数与常规函数的行为不同。在此类函数被调用时,他不会运行其代码。而是返回一个被称为“generator object”的特殊对象,来管理执行流程。
一个例子:
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generateSequence(); //创建了一个generator object
alert(generator); //[object Generator]
到目前为止,上面这段代码中的函数体还没有执行。
一个generator的主要方法就是next()。当被调用时,它会恢复运行,执行直到最近的yield <value>
语句(value默认为undefined)。然后函数执行暂停,并将产出的值返回到外部代码。
next()的结果始终是一个具有两个属性的对象:
-
value
:产出的(yielded)的值 -
done
:如果generator函数已执行完则为true,否则为false。
例如,我们可以创建一个generator并获取其第一个产出的(yielded)值:
function* generatorSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generatorSequence();
let one = generator.next();
alert(JSON.stringify(one)); // {value: 1, done: false}
之后依次执行next(),value的值分别变为2,3,当执行到return时,done的值变为true。
Generator是可迭代的,即可以通过for..of
循环遍历它所有的值,但是此时会忽略掉return所返回的值。
function* generatorSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generatorSequence();
for(let value of generator) {
alert(value); //1然后是2
}
当然也可以使用spread方法...
:
function* generatorSequence() {
yield 1;
yield 2;
yield 3;
}
let sequence = [0, ...generateSequence()];
alert(sequence); //0, 1, 2, 3