如何使用javascript中的生成器模拟同步调用?
假设下一段代码:如何使用javascript中的生成器模拟同步调用?,javascript,generator,ecmascript-6,co,Javascript,Generator,Ecmascript 6,Co,假设下一段代码: 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
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);
});
如您所见,我使用一个方法getFieldValue定义myObj。第一次调用此方法时,它将从数据库加载值。该值被缓存,在后续调用中,它直接返回该值。该解决方案非常有效,但对象的用户必须在生成器上下文中运行,并在每次访问对象方法之前编写一个yield
我可以假设所有调用都将在生成器上下文中完成。但是有没有办法重写myObj实现,以便用户不需要包含yield关键字
我希望用户可以在没有收益的情况下编写这样的内容:
co(function *() {
var v1 = myObj.getFieldValue();
console.log(v1);
var v2 = myObj.getFieldValue();
console.log(v2);
});
如果有帮助的话,我最近用C编写了第一个针对UNIX的rogue版本,并将其重写为javascript,以便在浏览器中工作。我使用了一种称为continuation的技术来等待用户输入密钥,因为在javascript中没有中断 所以我有一段C代码如下:
void function f() {
// ... first part
ch = getchar();
// ... second part
}
这将在未来发生变化
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();
}
}
然后将继续存储起来,以便在按键事件中重用。有了闭包,一切都会在停止的地方重新开始。使用ES6迭代器协议实现下一个方法会解决问题吗,例如,为什么要避免收益率?它们是生成器的关键元素,允许异步恢复吗?@Bergi,因为它很脏。我希望使用与myObj相同的api,而不关心它是同步实现还是异步实现的。var myObj={getFieldValue:function{returnthis.fieldValue;}}仅供参考。在@jbaylina中有一个关于这一点的大讨论:对我来说,让阻塞隐式化似乎很荒谬。但是,如果您已经在github或Escontract上发布了它,那么让我们在那里讨论这个问题。这是在javascript中执行常规异步调用的方法。我问的是另一件事。无论如何,非常感谢你的回答。