我正在尝试创建一个Node模块(使用和声),在被另一个模块/应用程序加载时,必须放弃它,这样它的构造中的东西可以在它的任何暴露函数被调用之前执行和加载。
我遇到的问题是,使用yield
,我似乎无法module.exports
执行正在执行的内部函数。一个例子会有所帮助。
module.exports = function*(s_id){
console.log('loading the module lets it execute up till here');
if (!(this instanceof Tester)) return yield new Tester();
}
function* Tester(){
console.log('but we never execute this generator function');
}
Tester.prototype = {
model : function*(){
// other functions
}
}
现在我已经好几个小时了!我觉得解决方案非常简单,但我似乎无法绕过它。我试图简单地使Tester()函数导出,但仍然有同样的问题。为什么我不能yield
看到Tester()函数?
此外,这种方法还有什么可替代的呢?我想维护模块的Object特性,以便模块可以加载不同的输入,例如上例中的 s_id 变量/对象。
答案 0 :(得分:1)
不要这样做。生成器不是异步的。一个节点模块(使用和声),在由另一个模块/应用程序加载时,必须被放弃,以便它的构造中的东西可以在其任何暴露的函数之前执行和加载被称为
yield
在这里没有做你想做的事。一个模块不会产生""等待加载中的内容。 yield
is magic, but not async magic
如果必须使用异步模块加载过程,请为实际模块导出承诺。这是一个等待的标准接口,可以使用不依赖于模块内部的标准化方法来使用。
您仍然可以使用return yield new Tester();
…
function* Tester(){…}
语法来构建该承诺,只需使用您喜欢的协程库。
哦,哦。是的,显然可以将生成器函数称为构造函数。但请相信我,这不是你想要的。任意对象的构造函数应该返回该对象,而不是迭代器(就像它shouldn't return a promise)。如果你的一些对象方法是生成器方法,那很好,但你的构造函数应该不是。yield*
如果您真的想在代码中使用生成器函数(并且它不是构造函数),那么
tester()
您创建的迭代器(yield
)而不是.prototype
function RichGeometry(c) {
c = (typeof c !== 'undefined') ? c : 0x00C020;
THREE.Geometry.call(this);
this.color = new THREE.Color(c);
}
属性,因为这会导致迭代器出现故障。 (当然你是should never do that at all,即使大部分时间都有效)