Generator函数的调用与普通函数一样,不一样的地方是:1,使用*标记Generator函数 2,Generator函数内部代码使用yield关键字返回数据并挂起程序,在调用next方法时才继续执行代码直到遇到下一个yield语句。也可以使用return 返回数据并终止Generator函数,即return后边的程序被忽略。Generator函数比较明显的意义是:1,让程序执行流挂起 2,让未实现迭代器的对象也能通过Generator函数实现迭代 3,某些场景下,跟异步编程(async/await,promise)实现某些功能,至于是哪些场景,遇到了再来补充。
1,Generator的使用:
//定义一个Generator函数。
var genFn = function*(){
console.log('hi');
yield 1;
console.log('hello');
yield 2;
}
//调用Generator函数。此时Generator函数内部逻辑被挂起,因此并未执行。
var generator = genFn(); //返回生成器Generator对象。
generator.next();
//控制台输出:
//'hi'
//{value: 1, done: false} //这是next方法的返回值
generator.next();
//控制台输出:
//'hello'
//{value: 2, done: false} //这是next方法的返回值
generator.next();
//控制台输出:
//{value: undefined, done: true} //内部逻辑的执行已完成
1.1, 若是在函数内部使用return,会提前告知内部逻辑结束执行,且return后面的逻辑被忽略:
var genFn = function*(){
console.log('hi');
yield 1;
console.log('hello');
return 2;
console.log('ha');
yield 3;
}
var generator = genFn();
generator.next();
//控制台输出:
//'hi'
//{value: 1, done: false}
generator.next();
//控制台输出:
//'hello'
//{value: 2, done: true}
generator.next();
//控制台输出:
//{value: undefined, done: true}
1.2,生成器还有两个方法:return、throw,这两个方法的使用如下:
//return方法用于结束执行
function* gnFn(){
yield 1;
yield 2;
}
var gn = gnFn();
gn.next();
//1
gn.return('hi'); //传参数是可选的,若未传参,则是undefined
//{value: 'hi', done: true}
gn.next();
//因generator调用return方法结束了后续执行,所以返回如下的值:
//{value: undefined, done: true}
//throw方法用于抛出错误,若程序执行流未结束,有try...catch...语句且未执行过,则能捕获异常
//如若不是,则异常会抛出生成器函数外。
function* gnFn(){
try{
yield(1);
yield(2);
}catch(e){
console.log('in gnFn ' + e);
}
}
var gn = gnFn();
try{
gn.next();//必须执行一次next方法,否则直接throw异常,Generator函数无法捕获异常。
gn.throw('hi');//被gnFn函数内部的try...catch..捕获。并结束程序执行。
console.log(gn.next());
gn.throw('hello');//此处抛出的异常被外部的try...catch..捕获。
gn.next(); //不会被执行。
}catch(e){
console.log('in global ' + e);
}
//输出
//'in gnFn hi'
//'in global hello'
//{value:undefined, done: true}
2,让对象能像数组一样使用 for...of..遍历,用Generator函数包装对象:
function* gnFn(obj){
var keys = Reflect.ownKeys(obj);//返回包含对象属性名的数组。
for(let key of keys){
yield [obj[key], key];
}
}
var obj = {
a: 'hi',
b: 'hello'
};
for(let[val, key] of gnFn(obj)){
console.log(key + ': ' + val);
}
//控制台输出
//'a: hi'
//'b: hello'
3,其他文档