ES6 生成器



ES6 生成器

ES6 生成器

生成器(或生成器函数)是 ES6 中引入的新概念。它为您提供了一种使用迭代器和函数的新方法。
ES6 生成器是一种不同的函数,可以在中间暂停一次或多次,稍后可以恢复。当标准函数被调用时,控制权在被调用的函数上,直到它返回,但 ES6 中的生成器允许调用者函数控制被调用函数的执行。

ES6 生成器_https://bianchenghao6.com_【ES6 教程】_第1张

生成器在某处与常规函数相同,除了那个:

当生成器被调用时,它不会运行它的代码。相反,它返回一个称为"生成器对象"的特殊对象,用于管理执行。
生成器函数可以随时将控制权返回(或让出)给调用者。
与常规函数不同,生成器可以根据要求一个接一个地返回(或产生)多个值。

语法

生成器函数的语法几乎与常规函数相同。唯一真正的区别是生成器函数由后缀函数关键字和星号(*)表示。
在以下语法中,我们向您展示了定义生成器函数的一些有效方法:
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);

输出
100
undefined
200

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); 
}

输出
A
E
I
O
U

注意: 不能使用箭头函数来表示生成器函数。