0

我正在尝试创建一个 Node 模块(使用 Harmony),在被另一个模块/应用程序加载时,必须屈服于它,以便在调用它的任何公开函数之前可以执行和加载它的构造中的东西。

我遇到的问题是我似乎无法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() 函数导出,但仍然遇到同样的问题。为什么我看不到yieldTester() 函数?

另外,这种方法有什么替代方法?我想保持模块的对象性质,以便模块可以加载不同的输入,例如上面示例中的s_id变量/对象。

4

1 回答 1

1

一个 Node 模块(使用 Harmony),在被另一个模块/应用程序加载时,必须让步,以便在调用它的任何公开函数之前可以执行和加载它的构造中的东西

不要那样做。生成器不是为异步而设计的。yield不在这里做你想做的事。一个模块不会“屈服”以等待其中的某些内容加载。yield是魔法,但不是异步魔法

如果您必须使用异步模块加载过程,请为您的实际模块导出一个承诺。这是等待某些东西的标准接口,并且可以使用不依赖于模块内部的标准化方法来使用。

您仍然可以使用yield语法来构建该承诺,只需使用您最喜欢的协程库即可。

return yield new Tester();
…
function* Tester(){…}

哦哦。是的,显然可以将生成器函数调用为构造函数。但相信我,这不是你想要的。任意对象的构造函数应该返回该对象,而不是迭代器(就像它不应该返回 promise一样)。如果您的某些对象方法是生成器方法,那很好,但您的构造函数不应该。

如果你真的想在你的代码中使用这样的生成器函数(并且它不是构造函数),你

  • 将需要yield*您创建的迭代器 ( tester()) 而不是yielding 它
  • 不能.prototype像你那样覆盖它的属性,因为这会导致迭代器发生故障。(当然你根本不应该这样做,即使它大部分时间都有效)
于 2015-04-25T20:59:03.893 回答