【问题标题】:Creating a yieldable Node Module/Object创建一个可屈服的节点模块/对象
【发布时间】:2015-07-04 08:58:11
【问题描述】:

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

我遇到的问题是,我似乎无法使用module.exports 对正在执行的内部函数进行yield。举个例子会有所帮助。

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 变量/对象。

【问题讨论】:

  • 你真的想在生成器函数上尝试new吗?

标签: node.js module generator ecmascript-harmony yield-keyword


【解决方案1】:

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

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

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

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

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

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

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

  • 将需要yield* 您创建的迭代器 (tester()) 而不是 yielding 它
  • 不能像您那样覆盖其.prototype 属性,因为这会导致迭代器发生故障。 (当然是你should never do that at all,尽管大部分时间它都有效)

【讨论】:

  • 这是一篇有趣的帖子——它给我提出了很多问题。我们的团队主要将生成器用作异步函数,因为所有意图和目的的暂停和恢复功能都模拟了异步行为。虽然您说它们不是为异步而“制造”的,但我认为它们经常用于此目的。例如:davidwalsh.name/async-generators。你为什么不建议这样使用它们?
  • 是的,它们可以用于异步,这很好(“为”我指的是主要目的)。只是,它们总是形成一个承诺,这是标准的异步接口。您应该导出它,而不是一些自定义的异步生成器。那些依赖于你的模块应该不需要知道你正在使用生成器来实现异步,隐藏你的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-08
  • 2017-04-07
  • 2021-12-21
  • 1970-01-01
  • 2017-02-14
  • 2019-12-31
相关资源
最近更新 更多