Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第五天:ES2015 Generator #7

Open
sofish opened this issue Apr 20, 2016 · 0 comments
Open

第五天:ES2015 Generator #7

sofish opened this issue Apr 20, 2016 · 0 comments
Milestone

Comments

@sofish
Copy link
Owner

sofish commented Apr 20, 2016

4 篇关于 Generator 的文章,从入门到放弃(CSP),里面有几个重要的点:

1. 使用 yieldreturn 导致 for...of 结果的不同

  function *foo() {
      yield 1;
      return 2;
  }

  var it = foo();

  console.log( it.next() ); // { value:1, done:false }
  console.log( it.next() ); // { value:2, done:true }

  for(let value of foo()) { 
    console.log(value)
  }

2. next() 可以传值

function *foo() {
    var x = 1 + (yield "foo");
    return x;
}

var it = foo();

console.log(it.next()); // 'foo'
console.log(it.next(1)); // 2

3. 在 Generator 嵌套 Generator 的顺序是怎样的?

当前迭代器会代理嵌套 Generator 的迭代器,流程如下:*bar() 的迭代器走到 yield *foo() 的点,进入 *foo() 完成迭代,再跳出来往下执行。

function *foo() {
    var z = yield 3;
    var w = yield 4;
    console.log( "z: " + z + ", w: " + w );
}

function *bar() {
    var x = yield 1;
    var y = yield 2;
    yield *foo(); // `yield*` delegates iteration control to `foo()`
    var v = yield 5;
    console.log( "x: " + x + ", y: " + y + ", v: " + v );
}

var it = bar();

it.next();      // { value:1, done:false }
it.next( "X" ); // { value:2, done:false }
it.next( "Y" ); // { value:3, done:false }
it.next( "Z" ); // { value:4, done:false }
it.next( "W" ); // { value:5, done:false }
// z: Z, w: W

it.next( "V" ); // { value:undefined, done:true }
// x: X, y: Y, v: V

4. 知名 Node.js 库 tj/co 的实现原理

基本上就是自执行 Generator 和 Promise 结合的结果。

// run (async) a generator to completion
// Note: simplified approach: no error handling here
function runGenerator(g) {
    var it = g(), ret;

    // asynchronously iterate over generator
    (function iterate(val){
        ret = it.next( val );

        if (!ret.done) {
            // poor man's "is it a promise?" test
            if (typeof ret.value.then === 'function') {
                // wait on the promise
                ret.value.then( iterate );
            }
            // immediate value: just send right back in
            else {
                // avoid synchronous recursion
                setTimeout( function(){
                    iterate( ret.value );
                }, 0 );
            }
        }
    })();
}

function *foo() {
    var z = yield 3;
    console.log(z);
    var w = yield 4;
    console.log(w);
}

function *bar() {
    var x = yield 1;
    console.log(x);
    var y = yield 2;
    console.log(y);
    yield *foo();
    var v = yield 5;
    console.log(v);
}

runGenerator(bar);

结:昨晚忘记更新了,这四篇写的非常好,我猜老婆也看不懂。在 async / await 出来之前,乖乖用 tj/co 就可以了。

@sofish sofish added this to the Daily Post milestone Apr 21, 2016
@sofish sofish closed this as completed Apr 22, 2016
@sofish sofish reopened this Apr 22, 2016
@sofish sofish changed the title 第五天:ES2016 Generator 第五天:ES2015 Generator May 23, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant