https://www.liaoxuefeng.com/wiki/1022910821149312/1023024381818112

1 菲波拉契数

  1. function* fib(max) {
  2. var
  3. t,
  4. a = 0,
  5. b = 1,
  6. n = 0;
  7. while (n < max) {
  8. yield a;
  9. [a, b] = [b, a + b];
  10. n ++;
  11. }
  12. return;
  13. }

直接调用试试:

  1. fib(5); // fib {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window}

直接调用一个generator和调用函数不一样,fib(5)仅仅是创建了一个generator对象,还没有去执行它。
调用generator对象有两个方法,

1-1 不断地调用generator对象的next()方法:

  1. var f = fib(5);
  2. f.next(); // {value: 0, done: false}
  3. f.next(); // {value: 1, done: false}
  4. f.next(); // {value: 1, done: false}
  5. f.next(); // {value: 2, done: false}
  6. f.next(); // {value: 3, done: false}
  7. f.next(); // {value: undefined, done: true}

next()方法会执行generator的代码,然后,每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。返回的value就是yield的返回值,done表示这个generator是否已经执行结束了。如果donetrue,则value就是return的返回值。
当执行到donetrue时,这个generator对象就已经全部执行完毕,不要再继续调用next()了。

1-2 第二个方法是直接用for ... of循环迭代generator对象,这种方式不需要我们自己判断done

  1. for (var x of fib(10)) {
  2. console.log(x); // 依次输出0, 1, 1, 2, 3, ...
  3. }