es6的学习笔记(五):generator
generator是一个简单的生成符合iterator协议的新特性。它可以方便的生成iterator,具有iterator的特性,也就是具有[Symbol.iterator],同时也有next()函数,同时可以使用for of,Array.from,[…]等操作。
调用generator函数,返回一个iterator对象,执行next()函数,会返回{value:value,done:boolean}。内部通过yield产生value,实例如下:
function* gen(){
yield 'hello'
yield 'hi'
return 'byebye'
};
let g = gen();
console.log(g.next().value);//hello
console.log(g.next().value);//hi
console.log(g.next().value);//byebye
console.log(g.next().value);//undefined
console.log(g.next().value);//undefined
其中,迭代器的next()执行顺序如下:
- 遇到yield语句,暂停执行后面的操作,并把紧跟在yield后面的值作为返回值。
- 下一次调用next()方法时,再继续往下运行,直到遇到下一个yield,如果next()函数有参数,则在一定条件下会进行赋值操作,然后再继续执行,第一次next的参数是无效的
- 如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。
- 如果该函数没有return语句,则返回的对象的value属性值为undefined。
var arr = [1, [[2, 3], 4], [5, 6]];
var flat = function* (a) {
var length = a.length;
for (var i = 0; i < length; i++) {
let y;
var item = a[i];
if (typeof item !== 'number') {
y=yield* flat(item);
console.log(y)
} else {
y=yield item;
console.log(y);
}
}
};
const s=flat(arr);
console.log(s.next('hi1').value); //1
console.log(s.next('hi2').value); //hi2 2
console.log(s.next('hi3').value); //hi3 3
const answers = [
`It is certain`,
`Yes definitely`,
`Most likely`,
`Yes`,
`Ask again later`,
`Better not tell you now`,
`Cannot predict now`,
`Don't count on it`,
`My sources say no`,
`Very doubtful`
]
function answer () {
return answers[Math.floor(Math.random() * answers.length)]
}
console.log(answer()) //每次运行都随机产生一句话
这个时候,可以写一个generator来产生一个无限序列,序列内容就是一个个随机的回答。generator的形式如下:
//version1
function* ball(){
while(true)
yield `[a] ${answer()}`
}
const g = ball();
console.log(g.next().value);
console.log(g.next().value);//随机产生一个回答
//version2
function* ball(){
let question;
while(true){
question = yield `[a] ${answer()}`
console.log(`[q] ${ question }`)
}
}
const g = ball()
g.next();//跳过第一个,因为第一个输入值不会影响输出,具体原因有待回头继续研究
console.log(g.next('hello?').value)//先输出[q],在输出[a]
console.log(g.next('hi?').value)
关于generator还有很多内容,有待后续继续挖掘