【发布时间】:2015-05-31 19:38:39
【问题描述】:
假设下一段代码:
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);
});
【问题讨论】:
-
使用 ES6 迭代器协议实现
next()方法是否可以解决问题,例如 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… -
为什么要避开
yields?它们是生成器的关键元素,并允许异步恢复? -
@Bergi 因为它是“脏的”。我想使用与 myObj 相同的 api,而不关心它是同步实现还是异步实现。 var myObj = { getFieldValue: function() { return this.fieldValue; } }
-
仅供参考。 esdiscuss.org/topic/does-async-await-solve-a-real-problem 对此有很大的讨论
-
@jbaylina:对我来说,隐含阻塞似乎很荒谬。但是让我们在 github 上讨论这个问题(或者如果你已经在 esdiscuss 那里发布了它)。
标签: javascript generator ecmascript-6 co