How can I emulate a synchronous call with generators in javascript?

自闭症网瘾萝莉.ら 提交于 2019-12-25 09:23:50

问题


Suppose the next piece of code:

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);
});

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.

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);
});

回答1:


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.

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.



来源:https://stackoverflow.com/questions/29301316/how-can-i-emulate-a-synchronous-call-with-generators-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!