概念
生成器是 ES6 中新增的一种特殊的函数,所以也称为“生成器函数”。它可以更灵活地控制函数什么时候执行, 什么时候暂停。
生成器是一种特殊的迭代器
返回值
调用生成器函数返回一个新的对应的生成器,
通过生成器next方法可以控制其迭代,next方法则返回下一个状态的生成器
由于生成器是一种特殊的迭代器,故生成器的属性与其类似
如下
{value: '', done: false}
其中 value为值,done则是是否完成迭代
生成器函数
定义一个生成器函数,我们需要在function
单词和函数名之间加一个*
符号
function* fn() { }
yield关键字
在生成器函数中通过yield来分割,每当执行时会暂停到下一个yield
(与yield同行的会被执行后暂停)
而value值可以通过 yield 赋予的值
赋值
举例如下
function* fn(){
console.log(1);
yield
console.log(2);
yield console.log(3);
console.log(4);
}
const f=fn()
console.log(f.next());//输出1 {value:undefined , done: false}
console.log(f.next());//输出2和3 {value:undefined , done: false}
console.log(f.next());//输出4 {value:undefined , done: true}
当通过yield赋值时,yield就不能与其他执行代码同行,否则会报错
或者加,隔开。但与yield也不会执行,会归为下一步骤
如下
function* fn(){
console.log(1);
yield 0
console.log(2);
//yield '1' console.log(3);会报错
yield '1'
console.log(3)
console.log(4);
}
const f=fn()
console.log(f.next());//1 {value:0 , done: false}
console.log(f.next());//2 {value:'1' , done: false}
console.log(f.next());//3和4 {value:undefined , done: true}
next的参数
next的参数会将值传给当前阶段(未执行当前next时)的所暂停的yield
如下
function* fn(){
console.log(yield );
console.log(yield);
console.log(yield);
}
const f=fn()
f.next(1)//不会被输出,因为第一次执行时没有暂停在yield
f.next(2)//输出
f.next(3)//输出
f.next(4)//输出
f.next(5)//已经迭代完成了,故不会输出
可以看出,有效的next方法个数就是yield+1个
如何中途结束生成器的执行
有三种方式:
- 方式1:return 语句。(与函数执行完则会结束同理)
- 方式2:通过生成器的 return() 函数。
- 方式3:通过生成器的 throw() 函数抛出异常
return的参数会返回给生成器的value
function* fn(){
console.log(yield );
console.log(yield);
console.log(yield);
}
const f=fn()
f.next(1)
f.next(2)
console.log( f.return(3));// {value:3 , done: true}
f.next(4)//已结束不会触发
function* fn(){
console.log(yield );
console.log(yield);
console.log(yield);
}
const f=fn()
f.next(1)
f.next(2)
console.log( f.throw(new Error('next2 error')));//Uncaught Error: next2 error
f.next(4)
使用 yield* 迭代可迭代对象
function* f(arr) {
for (const item of arr) {
yield item;
}
}
const myArr = ['a', 'b', 'c'];
const b = f(myArr);
console.log(b.next());
console.log(b.next());
console.log(b.next());
console.log(b.next());
///替换为
function* f(arr) {
yield* arr;
}
const myArr = ['a', 'b', 'c'];
const arrGenerator = f(myArr);
console.log(b.next());
console.log(b.next());
console.log(b.next());
console.log(b.next());