在javascript中实际使用双向生成器

时间:2015-12-29 02:20:11

标签: javascript

来自C#世界,我很想知道javascript中双向生成器的一些实际用法。我可以理解生成器在一般情况下是如何有用的,但在涉及双向生成器时则不然。我们可以将它与RxJS一起使用或喜欢吗?你能解释一下可以使用它的任何模式/场景吗?

function* interrogate() {
   let name = yield "What is your name?";
   let color = yield "What is your favorite color?";
   return `${name}'s favorite color is ${color}.`;
}

let it = interrogate();
it.next();         // { value: "What is your name?", done: false }
it.next('Ethan');  // { value: "What is your favorite color?", done: false }
it.next('orange'); // { value: "Ethan's favorite color is orange.", done:true }

1 个答案:

答案 0 :(得分:8)

David Walsh有blog about ES6 Generators

他有一个例子

function *foo(x) {
    var y = 2 * (yield (x + 1));
    var z = yield (y / 3);
    return (x + y + z);
}

var it = foo( 5 );

// note: not sending anything into `next()` here
console.log( it.next() );       // { value:6, done:false }
console.log( it.next( 12 ) );   // { value:8, done:false }
console.log( it.next( 13 ) );   // { value:42, done:true }

但同样,用例就像你的例子一样制造。

在他的总结中,他说

  

很自然地想知道这个新奇特玩具会做什么   实际上是为了你的代码。不过,对他们来说还有更多。我们'已经   只是划伤了表面。因此,我们必须先深入探讨   发现他们能够/将会有多强大。

     
      
  • 错误处理如何工作?
  •   
  • 一台发电机可以调用另一台发电机吗?
  •   
  • 异步编码如何与生成器一起使用?
  •   
     

这些问题以及更多问题将在后续文章中介绍   在这里,请继续关注!

In a later blog他有以下代码段(以及其他一些代码)

// 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 ("then" in ret.value) {
                // 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 );
            }
        }
    })();
}

runGenerator( function *main(){
    var result1 = yield request( "http://some.url.1" );
    var data = JSON.parse( result1 );

    var result2 = yield request( "http://some.url.2?id=" + data.id );
    var resp = JSON.parse( result2 );
    console.log( "The value you asked for: " + resp.value );
} );

这似乎更真实世界。

他总结了

  

简单地说:发电机+产生的承诺结合了两者的优点   世界,以获得真正强大和优雅的同步( - 看)异步流   控制表达能力。使用简单的包装器实用程序(其中   很多图书馆已经提供了),我们可以自动运行我们的   生成器完成,包括sane和sync(-looking)错误   处理!