【发布时间】:2014-08-15 10:16:13
【问题描述】:
我正在尝试为博客平台创建一个构造函数,它内部正在进行许多异步操作。这些范围包括从目录中抓取帖子、解析它们、通过模板引擎发送它们等等。
所以我的问题是,让我的构造函数返回一个 promise 而不是他们调用 new 反对的函数的对象是不明智的。
例如:
var engine = new Engine({path: '/path/to/posts'}).then(function (eng) {
// allow user to interact with the newly created engine object inside 'then'
engine.showPostsOnOnePage();
});
现在,用户也可以不提供补充的 Promise 链环:
var engine = new Engine({path: '/path/to/posts'});
// ERROR
// engine will not be available as an Engine object here
这可能会造成问题,因为用户可能会感到困惑,为什么 engine 在构建后不可用。
在构造函数中使用 Promise 的原因是有道理的。我希望整个博客在构建阶段之后能够正常运行。但是,在调用new 后几乎无法立即访问该对象似乎是一种气味。
我已经讨论过使用类似于engine.start().then() 或engine.init() 的东西来代替返回 Promise。但那些看起来也很臭。
编辑:这是在 Node.js 项目中。
【问题讨论】:
-
创建对象是异步操作还是获取资源真的是异步操作?如果你使用 DI,我认为你不会有这个问题
-
对于此类问题,我见过的最常见的设计模式是在构造函数中创建对象外壳,然后在
.init()方法中执行所有异步操作,然后可以返回承诺。然后从异步初始化操作中分离出对象中的实例数据和该对象的构造。当您在对象的初始化过程中出现各种不同的错误(调用者希望以不同的方式处理)时,也会出现同样的问题。从构造函数返回对象然后使用.init()返回其他东西会更好。 -
我完全同意 jfriend00。最好使用 init 方法来做出承诺!
-
@jfriend00 我还是不明白为什么。用这种方法编写和维护更多代码。
-
@KarlMorrison - 有关在创建新对象时执行异步操作的各种技术的讨论,请参阅Asynchronous Operations in Constructor。我个人的推荐是一个返回 promise 的工厂函数,因为没有办法意外误用该模式,而且界面清晰明了。
标签: javascript node.js architecture constructor promise