精读阮一峰 ECMAScript 6 入门 阶段2

110 阅读2分钟

es6提出的generator函数深入理解的话还是有很大深度的,特此做下笔记。

  console.log('执行了!')
}

var generator = f();

setTimeout(function () {
  generator.next()
}, 2000);

var arr = [1, [[2, 3], 4], [5, 6]];

var flat = function* (a) {
  a.forEach(function (item) {
    if (typeof item !== 'number') {
      yield* flat(item);
    } else {
      yield item;
    }
  });
};

var arr = [1, [[2, 3], 4], [5, 6]];

var flat = function* (a) {
  var length = a.length;
  for (var i = 0; i < length; i++) {
    var item = a[i];
    if (typeof item !== 'number') {
      yield* flat(item);
    } else {
      yield item;
    }
  }
};

for (var f of flat(arr)) {
  console.log(f);
}

var myIterable = {};
myIterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

[...myIterable] // [1, 2, 3]

function* dataConsumer() {
    console.log('Started');
    console.log(`1. ${yield}`);
    console.log(`2. ${yield}`);
    return 'result';
  }
  
  let genObj = dataConsumer();
  genObj.next();
  // Started
  genObj.next('a')
  // 1. a
  genObj.next('b')
  
function wrapper(generatorFunction) {
    return function (...args) {
        console.log('args',args,typeof args);
      let generatorObject = generatorFunction(...args);
      generatorObject.next();
      return generatorObject;
    };
  }

const wrapped = wrapper(function* () {
    console.log(`First input: ${yield}`);
    return 'DONE';
  });

  wrapped().next('hello!')

function* foo() {
    yield 1;
    yield 2;
    yield 3;
    yield 4;
    yield 5;
    return 6;
  }

  for (let v of foo()) {
    console.log(v);
  }

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
      yield curr;
      [prev, curr] = [curr, prev + curr];
    }
  }

  for (let n of fibonacci()) {
    if (n > 1000) break;
    console.log(n);
  }

function* objectEntries() {
    let propKeys = Reflect.ownKeys(this);
  
    for (let propKey of propKeys) {
      yield [propKey, this[propKey]];
    }
  }
  let jane = { first: 'Jane', last: 'Doe' };

// for (let [key, value] of objectEntries(jane)) {
//   console.log(`${key}: ${value}`);
// }

jane[Symbol.iterator] = objectEntries;

for (let [key, value] of jane) {
  console.log(`${key}: ${value}`);
}

var g = function* () {
    try {
      yield;
    } catch (e) {
      console.log('内部捕获', e);
    }
  };
  var i = g();
i.next();
try {
    i.throw('a');
    i.throw('b');
  } catch (e) {
    console.log('外部捕获', e);
  }

var g = function* () {
    while (true) {
      try {
        yield;
      } catch (e) {
        if (e != 'a') throw e;
        console.log('内部捕获', e);
      }
    }
  };

  var i = g();
i.next();

try {
  throw new Error('a');
  throw new Error('b');
} catch (e) {
  console.log('外部捕获', e);
}

var gen = function* gen(){
    yield console.log('hello');
    yield console.log('world');
  }
  
  var g = gen();
  g.next();
  g.throw();

var gen = function* gen(){
    try {
      yield console.log('a');
    } catch (e) {
      // ...
    }
    yield console.log('b');
    yield console.log('c');
  }
  
  var g = gen();
  g.next() // a
  g.throw() // b
  g.next() // c

function* foo() {
    var x = yield 3;
    var y = x.toUpperCase();
    yield y;
  }
  
  var it = foo();
  
  console.log(it.next()); // { value:3, done:false }
  
  try {
    it.next(42);
  } catch (err) {
    console.log(typeof err,err.message);
  }

function* g() {
    yield 1;
    console.log('throwing an exception');
    throw new Error('generator broke!');
    yield 2;
    yield 3;
  }

  function log(generator) {
    var v;
    console.log('starting generator');
    try {
      v = generator.next();
      console.log('第一次运行next方法', v);
    } catch (err) {
      console.log('捕捉错误', v);
    }
    try {
      v = generator.next();
      console.log('第二次运行next方法', v);
    } catch (err) {
      console.log('捕捉错误', v);
    }
    try {
      v = generator.next();
      console.log('第三次运行next方法', v);
    } catch (err) {
      console.log('捕捉错误', v);
    }
    console.log('caller done');
  }
  
  log(g());

function* foo() {
    yield 'a';
    yield 'b';
  }

//   function* bar() {
//     yield 'x';
//     // 手动遍历 foo()
//     for (let i of foo()) {
//     //   console.log(i);
//     }
//     yield 'y';
//   }

function* bar() {
    yield 'x';
    yield* foo();
    yield 'y';
  }

  for (let v of bar()){
    console.log(v);
  }

function* inner() {
    yield 'hello!';
  }
  
  function* outer1() {
    yield 'open';
    yield inner();
    yield 'close';
  }
  
  var gen = outer1()
  gen.next().value // "open"
console.log(  gen.next().value); // 返回一个遍历器对象
  gen.next().value // "close"

let delegatedIterator = (function* () {
    yield 'Hello!';
    yield 'Bye!';
  }());

  let delegatingIterator = (function* () {
    yield 'Greetings!';
    yield* delegatedIterator;
    yield 'Ok, bye.';
  }());

  for(let value of delegatingIterator) {
    console.log(value);
  }

function* concat(iter1, iter2) {
    yield* iter1;
    yield* iter2;
  }
  
function* gen(){
    yield* ["a", "b", "c"];
  }

console.log(gen().next());

function* foo() {
    yield 2;
    yield 3;
    return "foo";
  }

  function* bar() {
    yield 1;
    var v = yield* foo();
    console.log("v: " + v);
    yield 4;
  }
  
  var it = bar();
  
function* genFuncWithReturn() {
    yield 'a';
    yield 'b';
    return 'The result';
  }

  function* logReturned(genObj) {
    let result = yield* genObj;
    console.log(result);
  }

  console.log([...logReturned(genFuncWithReturn())]);

function* iterTree(tree) {
    if (Array.isArray(tree)) {
      for(let i=0; i < tree.length; i++) {
        yield* iterTree(tree[i]);
      }
    } else {
      yield tree;
    }
  }

  const tree = [ 'a', ['b', 'c'], ['d', 'e'] ];

  for(let x of iterTree(tree)) {
    console.log(x);
  }

console.log([...iterTree(tree)]);

function Tree(left, label, right) {
    this.left = left;
    this.label = label;
    this.right = right;
  }

  function* inorder(t) {
    if (t) {
      yield* inorder(t.left);
      yield t.label;
      yield* inorder(t.right);
    }
  }

  function make(array) {
    // 判断是否为叶节点
    if (array.length == 1) return new Tree(null, array[0], null);
    return new Tree(make(array[0]), array[1], make(array[2]));
  }
  let tree = make([[['a'], 'b', ['c']], 'd', [['e'], 'f', ['g']]]);

  var result = [];
for (let node of inorder(tree)) {
  result.push(node);
}

console.log(result);

function* F() {
    this.a = 1;
    yield this.b = 2;
    yield this.c = 3;
  }

  var obj = {};
var f = F.call(obj);

function* gen() {
    this.a = 1;
    yield this.b = 2;
    yield this.c = 3;
  }

  function F() {
    return gen.call(gen.prototype);
  }

  var f = new F();

f.next();  // Object {value: 2, done: false}
f.next();  // Object {value: 3, done: false}
f.next();  // Object {value: undefined, done: true}

console.log(f.a);

function* gen() {
    yield 1;
    return 2;
  }
  
  let g = gen();
  
  console.log(
    g.next().value,
    g.next().value,
  );

function* iterEntries(obj) {
    let keys = Object.keys(obj);
    for (let i=0; i < keys.length; i++) {
      let key = keys[i];
      yield [key, obj[key]];
    }
  }

  let myObj = { foo: 3, bar: 7 };

for (let [key, value] of iterEntries(myObj)) {
  console.log(key, value);
}

function* makeSimpleGenerator(array){
    var nextIndex = 0;
  
    while(nextIndex < array.length){
      yield array[nextIndex++];
    }
  }

  var gen = makeSimpleGenerator(['yo', 'ya']);