美文网首页
认识generator

认识generator

作者: meteornnnight | 来源:发表于2019-08-24 15:34 被阅读0次

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

相关文章

网友评论

      本文标题:认识generator

      本文链接:https://www.haomeiwen.com/subject/bcxqectx.html