特点:
①function关键字与函数名之间有个星号*;
②函数体内部使用yield表达式,定义不同的内部状态(yield“产出”)
function* helloWorldGenerator () {
yield "hello";
yield "world";
return "ending";
}
var hw = helloworldGenerator();
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
第一次调用,Generator 函数开始执行,直到遇到第一个yield表达式为止。next方法返回一个对象,它的value属性就是当前yield表达式的值hello,done属性的值false,表示遍历还没有结束。
第二次调用,Generator 函数从上次yield表达式停下的地方,一直执行到下一个yield表达式。next方法返回的对象的value属性就是当前yield表达式的值world,done属性的值false,表示遍历还没有结束。
第三次调用,Generator 函数从上次yield表达式停下的地方,一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。
第四次调用,此时 Generator 函数已经运行完毕,next方法返回对象的value属性为undefined,done属性为true。以后再调用next方法,返回的都是这个值。
function* fibs() {
let a = 0;
let b = 2;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
//上来先执行自己的a=0,然后再累加
console.log(first,second,third,fourth,fifth,sixth) //0 2 2 4 6 10
应用:通过generator进行异步函数调用
function one() {
setTimeout(()=>{
console.log(111);
iterator.next();
},1000)
}
function two() {
setTimeout(()=>{
console.log(222);
iterator.next();
},2000)
}
function three() {
setTimeout(()=>{
console.log(333);
iterator.next();
},3000)
}
function* gen() {
yield one();
yield two();
yield three();
}
//调用生成器函数
let iterator=gen();
iterator.next();