es6 generator 生成器
定义
生成器是用于生产生成器对象的特殊函数
生成器对象现了迭代器接口iterator,生成器对象也是一个迭代器,通过next()函数分步执行生成器函数内的代码
// 定义一个生成器,在普通函数的function后面加一个'*',就成为生成器了
function* mGenerator() {
}
// 或者下面写法
let mGenerator = function* () {
}
必须是function定义的函数,不能是箭头函数
用法
定义一个生成器
let mGenerator = function* () {
console.log('一个生成器');
}
执行next()函数
// 生成一个生成器对象,此时并没有执行生成器内的代码
let generator = mGenerator()
console.log(generator);
// 调用生成器对象的next()函数,执行生成器函数内的代码
console.log(generator.next());
控制台输出结果
Object [Generator] {}
一个生成器
{ value: undefined, done: true }
yield 关键字
yield 基础用法
yield关键字只能用在生成器中,用于分割生成器函数
// 通过两个yield将生成器函数代码分为三部分
let mGenerator = function* () {
console.log('11');
yield
console.log('22');
yield
console.log('33');
}
let generator = mGenerator()
// 第一次调用next()函数会执行第一个yield之前的代码
console.log(generator.next());
// 第二次调用next()函数会执行第一个yield和第二个yield之间的代码
console.log(generator.next());
// 第三次调用next()函数会执行第二个yield之后的代码
// 第三次调用next()返回的对象中done属性为true,表示生成器对象执行完成
// 如果后续再调用next()函数不会再执行生成器内的代码
console.log(generator.next());
console.log(generator.next());
输出结果
11
{ value: undefined, done: false }
22
{ value: undefined, done: false }
33
{ value: undefined, done: true }
{ value: undefined, done: true }
yield接收和返回参数
可以使用yield接收和返回参数
let mGenerator = function* (v) {
console.log(v);
v = yield v
console.log(v)
return v
}
let generator = mGenerator(0)
console.log(generator.next(1));
console.log(generator.next(2));
控制台输出
0
{ value: 0, done: false }
2
{ value: 2, done: true }
代码分析
首先初始化生成器mGenerator
let generator = mGenerator(0)
执行第一行代码生成一个生成器对象,此时generator中的v为0
console.log(generator.next(1));
// { value: 0, done: false }
执行第二行代码,调用generator.next(1),此时generator中的v为0,next(1)执行的代码为yield上面的代码以及v = yield v
这段代码的后半段yield v
,传入的1并没有yield或者其他参数接收
执行完yield前面的代码之后,代码yield v
相当于return v
通过返回对象的’value’属性将v返回,
console.log(generator.next(2));
// { value: 2, done: true }
调用next(2)函数,代码从’v = yield’开始执行,相当于把2赋值给v
最后面’return v’将v返回,赋值给next(2)返回的对象的’value’属性
yield*
通过yield*可以对迭代一个可迭代对象
let mGenerator = function* (v) {
yield*v
}
let generator = mGenerator([1,2,3])
console.log(generator.next());
console.log(generator.next());
console.log(generator.next());
控制台输出
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
终止生成器
通过生成器对象的return()终止生成器
通过控制器对象的return()函数终止执行后面的代码
let mGenerator = function* (v) {
console.log(`yield前面的v=${v}`);
v = yield v
console.log(`yield后面的v=${v}`);
return v
}
let generator = mGenerator(1)
console.log(generator.next(2));
// 调用return函数之后,后续再调用next函数,也不会执行任何代码
console.log(generator.return(0));
console.log(generator.next(3));
控制台输出
yield前面的v=1
{ value: 1, done: false }
{ value: 0, done: true }
{ value: undefined, done: true }
通过生成器对象的throw()终止生成器
通过生成器对象的throw()函数手动抛出异常终止生成器
如果生成器内部通过try-catch处理异常,则不会终止生成器代码的执行
演示代码-生成器不处理异常
let mGenerator = function* (v) {
console.log(`yield前面的v=${v}`);
v = yield v
console.log(`yield后面的v=${v}`);
return v
}
let generator = mGenerator(1)
console.log(generator.next(2));
try {
console.log(generator.throw(0));
}catch (e) {
}
控制台输出
yield前面的v=1
{ value: 1, done: false }
{ value: undefined, done: true }
演示代码-生成器处理异常
let mGenerator = function* (v) {
console.log(`yield前面的v=${v}`);
try {
v = yield v
}catch (e) {
}
console.log(`yield后面的v=${v}`);
return v
}
let generator = mGenerator(1)
console.log(generator.next(2));
try {
console.log(generator.throw(0));
}catch (e) {
}
控制台输出
yield前面的v=1
{ value: 1, done: false }
yield后面的v=1
{ value: 1, done: true }