2020年5月6日 作者 zeroheart

ES6中的Generator

先看一下下面的这个写法

function * helloGenerator(){
console.info("hello generator!");
}
helloGenerator();

如果是普通的函数,执行helloGenerator()后,应该会打印出hello generator!,实际上,这里并没有相关的日志输出。

让我们把例子修改一下

function * helloGenerator(){
console.info("hello generator!");
}
var h = helloGenerator();
h.next();//输出日志

h表示helloGenerator方法的一个引用,可以调用next()方法。为什么可以调用next(),是因为Generator实现了迭代器Itearator接口。

例子在改一下

//example 1
function * helloGenerator(){
yield "i";
yield "am";
yield "a";
yield "generator";
return "done";
}
var h = helloGenerator();
console.info(h.next()); //{value: "i", done: false}
console.info(h.next()); //{value: "am", done: false}
console.info(h.next()); //{value: "a", done: false}
console.info(h.next()); //{value: "generator", done: false}
console.info(h.next()); //{value: "done", done: true}
//example 2
function * helloGenerator(){
yield "i";
yield "am";
yield "a";
yield "generator";
return "done";
}
var h = helloGenerator();
for(var v of h){
console.info(v);
}

例子1中,每次执行next()方法,到达yield关键字,会返回yield后的内容,包含返回值和generator的done状态,并暂停整个函数的执行。例子2中展示了,generator的迭代性。

我们可以把h.next()的值接收后,传递给next()函数,如下面的例子

function * helloGenerator(x, y){
let z = yield x+y;
let result = yield z*x;
return result
}
var h = helloGenerator(3,5);
console.info(h.next());// {value: 8, done: false}
console.info(h.next());// {value: NaN, done: false}
function * helloGenerator(x, y){
let z = yield x+y;
let result = yield z*x;
return result
}
var h = helloGenerator(3,5);
var sum = h.next();
console.info(h.next(sum.value));
function * helloGenerator(x, y){
let z;
let result;
yield z = x+y;
yield result = z*x;
return result
}
var h = helloGenerator(3,5);
console.info(h.next());
console.info(h.next());

迭代器除了可以调用next()方法,还可以调用return方法,return方法也可以带有返回值。return调用之后,后面的next,将返回undefined。

generator可以方便的让出或者得到函数执行权。运用yield关键字和generator函数,可以优化异步编程的流程控制,减少回调。