03-生成器
12.2 生成器
生成器是使用迭代器来控制其运行的函数。一般来说,函数会获取参数然后返回结果,但是函数调用者并没办法控制该函数。当调用一个函数的时候,实际上是放弃了对函数的控制,直到函数返回。有了生成器,就可以在函数执行时对它进行控制。
生成器提供了两种能力:首先,是控制函数执行的能力,使函数能够分步执行;其次,是与执行中的函数对话的能力。
生成器与一般的函数有两个不同的地方:
- 函数可以通过使用yield,在其运行的任意时刻将控制权交还给调用方。
- 调用生成器的时候,它并不是立即执行。而是会回到迭代器中。函数会在调用迭代器的next方法时执行。
在JavaScript中,生成器需要在 function 关键字后添加一个通配符(*)来指明;其他情况下,它的语法跟普通函数一样。如果一个函数是生成器,就可以在 return 中添加 yield 关键字了。
下面来看一个简单的例子,一个返回彩虹中所有颜色的生成器:
function* rainbow() { // 通配符让它变成了一个生成器
yield 'red';
yield 'orange';
yield 'yellow';
yield 'green';
yield 'blue';
yield 'indigo';
yield 'violet';
}
接下来看看如何调用这个生成器。记住,当调用生成器的时候,实际上是回到了迭代器中。下例中将会调用这个函数,然后逐步调用迭代器:
const it = rainbow();
it.next(); // { value: "red", done: false }
it.next(); // { value: "orange", done: false }
it.next(); // { value: "yellow", done: false }
it.next(); // { value: "green", done: false }
it.next(); // { value: "blue", done: false }
it.next(); // { value: "indigo", done: false }
it.next(); // { value: "violet", done: false }
it.next(); // { value: undefined, done: true }
因为 rainbow 生成器返回了一个迭代器,所以也可以对它使用 for…of 循环:
for(let color of rainbow()) {
console.log(color):
}
这段代码会将彩虹中所有的颜色都输出到控制台中!