js生成器
文章目录
- 概念
- 生成器函数
- 如何中途结束生成器的执行
- 使用 yield* 迭代可迭代对象
概念
生成器是 ES6 中新增的一种特殊的函数,所以也称为“生成器函数”。它可以更灵活地控制函数什么时候执行, 什么时候暂停。
生成器是一种特殊的迭代器
返回值
调用生成器函数返回一个新的对应的生成器,
通过生成器next方法可以控制其迭代,next方法则返回下一个状态的生成器
由于生成器是一种特殊的迭代器,故生成器的属性与其类似
如下
{value: '', done: false}
其中 value为值,done则是是否完成迭代
生成器函数
定义一个生成器函数,我们需要在function
单词和函数名之间加一个*
符号
function* fn() { }
yield关键字
在生成器函数中通过yield来分割,每当执行时会暂停到下一个yield
(与yield同行的会被执行后暂停)
而value值可以通过 yield 赋予的值
赋值
举例如下
function* fn(){console.log(1);yieldconsole.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 0console.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)//不会被输出,因为第一次执行时没有暂停在yieldf.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 errorf.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());