ES6 生成器
ES6 生成器
生成器(或生成器函数)是 ES6 中引入的新概念。它为您提供了一种使用迭代器和函数的新方法。
ES6 生成器是一种不同的函数,可以在中间暂停一次或多次,稍后可以恢复。当标准函数被调用时,控制权在被调用的函数上,直到它返回,但 ES6 中的生成器允许调用者函数控制被调用函数的执行。
生成器在某处与常规函数相同,除了那个:
当生成器被调用时,它不会运行它的代码。相反,它返回一个称为"生成器对象"的特殊对象,用于管理执行。
生成器函数可以随时将控制权返回(或让出)给调用者。
与常规函数不同,生成器可以根据要求一个接一个地返回(或产生)多个值。
语法
生成器函数的语法几乎与常规函数相同。唯一真正的区别是生成器函数由后缀函数关键字和星号(*)表示。
在以下语法中,我们向您展示了定义生成器函数的一些有效方法:
function* mygenfun() // Valid
{
yield 1;
yield 2;
...
...
}
function *mygenfun() // Valid
{
yield 1;
yield 2;
...
...
}
function*mygenfun() // Valid
{
yield 1;
yield 2;
...
...
}
示例
function* gen()
{
yield 100;
yield;
yield 200;
}
// Calling the Generator Function
var mygen = gen();
console.log(mygen.next().value);
console.log(mygen.next().value);
console.log(mygen.next().value);
输出
yield 语句
yield 语句暂停函数执行并将值发送回调用者。它保留了足够的状态,使功能能够从中断的地方恢复。当它恢复时,该函数会在最后一次 yield 运行后立即继续执行。它可以产生一系列值。
next() 方法
在上面的例子中,我们使用了next() 方法,这是生成器的主要方法。当您将 next() 方法与参数一起调用时,它将恢复生成器函数的执行,替换执行暂停的 yield 表达式next() 方法。
next() 方法的结果始终是一个具有两个属性的对象:
价值: 它是产生的价值。
done: 它是一个布尔值,如果函数代码已完成则返回真。否则,它会报错。
例如,在这里,我们正在创建一个生成器函数并获取其产生的值。
示例
function* show() {
yield 100;
}
var gen = show(); //here 'gen' is a generator object
console.log(gen.next()); // { value: 100, done: false }
输出
{ value: 100, done: false }
生成器对象
生成器函数返回生成器对象。生成器对象是生成器函数的实例,它同时符合可迭代和迭代器接口。
生成器对象可以通过调用next() 方法使用或者通过在循环中使用生成器对象。生成器对象是一个迭代器;这就是为什么您可以在 for...of 循环或其他接受可迭代对象的函数中使用它。
在上面的 next() 方法示例中,变量 gen 是生成器对象。
生成器中的返回语句
返回用于将指定值发送回其调用者.它用于结束函数调用执行并将结果返回给调用者。在函数内,不执行 return 语句之后定义的语句。这就是为什么 return 语句应该是函数的最后一个语句。
让我们通过一个例子来尝试理解生成器中的 return 语句:
示例
function* myGen() {
yield 'First yield statement';
yield 'Second yield statement';
return 'return statement';
yield 'Second yield statement';
}
let genobj = myGen();
console.log(genobj.next()); //returns {value: 'First yield statement', done: false}
console.log(genobj.next()); //returns {value: 'Second yield statement', done: false}
console.log(genobj.next()); //returns {value: 'return statement', done: true}
console.log(genobj.next()); //returns {value: undefined, done: true}
输出
{ value: 'First yield statement', done: false }
{ value: 'Second yield statement', done: false }
{ value: 'return statement', done: true }
{ value: undefined, done: true }
在上面的例子中,我们定义了一个生成器函数myGen(),其中我们定义了四个语句,包括三个yield语句和一个return陈述。 每当我们调用 next() 方法时,该函数都会恢复,直到遇到下一个 yield 语句。
您可以注意到第一个 next() 方法返回 '第一个 yield 语句。' 当我们第二次调用next()方法时,它会恢复执行并返回'第二个yield语句'。再次调用next()方法后,该函数不再找到yield语句并返回'Return语句'。 但是当我们第四次调用next()方法时,它不会考虑yield语句并返回undefined,因为它是写在 return 语句之后。
你可以在上面例子的输出中看到 next() 方法没有考虑后面的任何语句return 语句。
带 for...of 循环的生成器函数
使用带生成器函数的 for...of 循环减少了代码行。您可以在以下示例中看到相同的插图。
示例
"use strict"
function* vowels() {
// here the asterisk marks this as a generator
yield 'A';
yield 'E';
yield 'I';
yield 'O';
yield 'U';
}
for(let alpha of vowels()) {
console.log(alpha);
}
输出
注意: 不能使用箭头函数来表示生成器函数。