1. 基本用法和next()
函数
function* generatorSeq(index){
while(index<3){
yield index++;
}
}
let generator=generatorSeq(0);
console.log(generator.next().value); //0
console.log(generator.next().value); //1
console.log(generator.next().value); //2
console.log(generator.next().value); //undefined, done: true.
//generator is iterable.
for(var i of generator){
console.log(i); //0,1,2
}
2. 迭代
generator
的这一特性能够很好地应用在定义对象的迭代上:
我们之前是这么创建一个可迭代的(能够被for...of
迭代)对象的:
let range={
from: 0,
to: 5
};
range[Symbol.iterator] = function() {
// ...it returns the iterator object:
// 2. Onward, for..of works only with this iterator, asking it for next values
return {
current: this.from,
last: this.to,
// 3. next() is called on each iteration by the for..of loop
next() {
// 4. it should return the value as an object {done:.., value :...}
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
};
我们可以完美地利用generator
来实现:
let range={
from: 0,
to: 5,
[Symbol.iterator]: function* (){
for(let i=this.from;i<this.to;i++){
yield i;
}
}
};
console.log(...range);//0,1,2,3,4
3. generator
组合
function* generateSequence(start, end) {
for (let i = start; i <= end; i++) yield i;
}
function* generateAlphaNum() {
// yield* generateSequence(48, 57);
for (let i = 48; i <= 57; i++) yield i;
// yield* generateSequence(65, 90);
for (let i = 65; i <= 90; i++) yield i;
// yield* generateSequence(97, 122);
for (let i = 97; i <= 122; i++) yield i;
}
let str = '';
for(let code of generateAlphaNum()) {
str += String.fromCharCode(code);
}
alert(str); // 0..9A..Za..z
4. yield
双向数据流
一直到现在,我们都将generator
作为迭代器来使用,确实这是它及其方便的应用。但generator
还远远不止这些用处。我们可以通过.next(args)
来传递并决定generator
函数内部yield
的结果。
function* gen() {
let ask1 = yield "2 + 2?";
alert(ask1); // 4
let ask2 = yield "3 * 3?"
alert(ask2); // 9
}
let generator = gen();
alert( generator.next().value ); // "2 + 2?"
alert( generator.next(4).value ); // "3 * 3?" (*)
alert( generator.next(9).done ); // true

上述代码(*)处,
generator.next(4).value
这个语句把4
传递给了generator
,让它恢复执行,执行到第二个yield
处,generator
传递回calling code
第二个yield
的值。
5. throw error
有的时候我们需要向generator
函数内部传递error
,比如数据库中没有找到对应的数据,那我们需要调用generator.throw()
function* gen(){
let result = yield "user_id=20111";
}
var g = new gen();
var result = gen.next().value;
try{
gen.throw(new Error('no user data'));
}catch(e){
console.log(e);
}
也可以把try...catch...
语句放在generator
函数内部:
function* gen(){
try {
let result = yield "user_id=20111";
}catch(e){
console.log(e);
}
}
var g = new gen();
var result = gen.next().value;
gen.throw(new Error('no user data'));
6. 随机数生成器
function* pseudoRandom(seed) {
let value = seed;
while(true) {
value = value * 16807 % 2147483647
yield value;
}
};
let generator = pseudoRandom(1);
alert(generator.next().value); // 16807
alert(generator.next().value); // 282475249
alert(generator.next().value); // 1622650073
网友评论