Generator函数是es6引入的异步操作函数,不同于普通函数,Generator函数可以通过yield关键字对执行流程挂起,从而对异步编程的实现。语法上,Generator函数是一个状态机,有多个内部状态,执行Generator函数会返回一个遍历器对象;形式上,Generator函数也是一个普通函数,使用关键字function定义。
Generator函数语法
使用function定义函数,函数名前面有一个*
号,函数内部有yield表达式。
function* myFun(){
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
}
调用Generator函数和调用普通函数一样,但Generator函数不会立即执行,而是返回一个指向内部状态的指针,需要调用遍历器对象Iterator的next方法,指针就会从函数头部往下依次执行。
function* myFun(){
console.log("one");
yield '1';
console.log("two");
yield '2';
console.log("three");
return '3';
}
var f = myFun();
f.next();//one
f.next();//two
f.next();//three
f.next();//
Generator函数执行完后,返回的遍历器对象的状态done属性为true。
遍历器对象的方法
next方法:next方法是Generator函数执行必须会调用的方法,next方法的参数会作为yield表达式的返回值传递。
function* my(){
console.log("start");
var x = yield '2';
console.log("one = "+x);
var y = yield '3';
console.log("two = "+y)
console.log("x + y = "+(x+y));
}
//没有参数
var m = my();
m.next();//start
m.next();//one = undefined
m.next();//two = undefined x + y = NaN
next 带参数的情况
function* my(){
console.log("start");
var x = yield '2';
console.log("one = "+x);
var y = yield '3';
console.log("two = "+y)
console.log("x + y = "+(x+y));
}
//没有参数
var m = my();
m.next(0);//start
m.next(1);//one = 1
m.next(2);//two = 2 x + y = 3
除了使用 next ,还可以使用 for... of 循环遍历 Generator 函数生产的 Iterator 对象。
return方法:return 方法返回给定值,并结束遍历 Generator 函数。return 方法提供参数时,返回该参数;不提供参数时,返回 undefined 。
function* fun(){
yield 1;
yield 2;
yield 3;
}
var f = fun();
f.next();
f.return(2);//结束函数并返回2
throw方法:throw 方法可以再 Generator 函数体外面抛出异常,再函数体内部捕获。
var fun = function* () {
try {
yield;
} catch (e) {
console.log('catch inner', e);
}
};
var f = fun();
f.next();
try {
f.throw('a');//catch inner a
f.throw('b');//catch outside b
} catch (e) {
console.log('catch outside', e);
}
yield*
:yield*
表达式表示 yield 返回一个遍历器对象,用于在 Generator 函数内部,调用另一个 Generator 函数。
function* fun(){
console.log("fun..." + (yield));
}
function* myFun(){
while(true){
yield* fun();
}
}
var my = myFun();
my.next();//
my.next(1);//fun...1
my.next(2);//fun...2
// 等同于
function* fun() {
while (true) {
for (var value of fun) {
yield value;
}
}
}
Generator函数返回的遍历器对象的特性,可以使用Generator函数为不具备 Iterator 接口的对象提供遍历方法。