问题
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