如何在javascript中使用生成器模拟同步调用? [英] How can I emulate a synchronous call with generators in javascript?

查看:150
本文介绍了如何在javascript中使用生成器模拟同步调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设下一段代码:

var co = require('co');

var myObj = {
    getFieldValue: function() {
        var self = this;
        console.log(JSON.stringify(self));
        if (!self.fieldValue) {
            return function(cb) {
                // Emulate an async database load
                setTimeout(function() {
                    self.fieldValue = "the value from the database\n";
                    cb(null, self.fiedValue);
                }, 5000);
            };
        } else {
             return function(cb) {
                cb(null, self.fieldValue);
            };
        }
    },
};

co(function *() {
    var v1 = yield myObj.getFieldValue();
    console.log(v1);
    var v2 = yield myObj.getFieldValue();
    console.log(v2);
});

如您所见,我用单一方法定义了 myObj > getFieldValue 。第一次调用此方法时,会从数据库加载值。值被缓存,在后续调用中,它直接返回值。解决方案非常有用,但是对象的用户必须在生成器上下文中运行,并在每个对象方法访问前面写出一个yield。

As you can see, I define myObj with a single method getFieldValue. The first time this methods is called, it loads the value from the database. The value is cached and, in subsequent calls, it returns the value directly. The solution works great, but the user of the object must run in a generator context and write a yield in front of each access to the object methods.

我可以假设所有的调用都将在生成器上下文中完成。但是有没有办法重写 myObj 实现,以便用户不需要包含yield关键字?

I can assume that all calls will be done in a generator context. But is there a way to rewrite the myObj implementation so that the user does not need to include the yield keyword?

我想要用户可以写一些这样的东西(没有收益):

I would like the user could write some thing like this (without the yields):

co(function *() {
    var v1 = myObj.getFieldValue();
    console.log(v1);
    var v2 = myObj.getFieldValue();
    console.log(v2);
});


推荐答案

如果有帮助,我最近拿了第一个版本在C中为UNIX编写的流氓,并重写了JavaScript以在浏览器中工作。我使用了一个名为继续的技术,能够等待用户输入密钥,因为在javascript中没有中断。

If it helps, I recently took the first release of the rogue written for UNIX in C and rewrote it for javascript to work in a browser. I used a technic called continuation to be able to wait for key entry by the user because in javascript the are no interrupts.

所以我会有一块C代码这个:

So I would have a piece of C code like this:

void function f() {

  // ... first part

  ch = getchar();

  // ... second part

}



that would be transformed in

function f(f_higher_cont) {

  // ... first part

  var ch = getchar(f_cont1);

  return;
  // the execution stops here 

  function f_cont1 () {

    // ... second part
    f_higher_cont();
  }
}

然后将继续存储以便在密钥事件。随着关闭,所有的东西都将重新启动,在那里它被搁置。

the continuation is then stored to be reuse on a keypressed event. With closures everything would be restarted where it stoped.

这篇关于如何在javascript中使用生成器模拟同步调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆