Я столкнулся с той же проблемой и придумал это простое решение.
Вместо того, чтобы возвращать Promise из конструктора, поместите его в свойство this.initialization
, например:
function Engine(path) {
var engine = this
engine.initialization = Promise.resolve()
.then(function () {
return doSomethingAsync(path)
})
.then(function (result) {
engine.resultOfAsyncOp = result
})
}
Затем оберните каждый метод в обратном вызове, который запускается после инициализации, например:
Engine.prototype.showPostsOnPage = function () {
return this.initialization.then(function () {
// actual body of the method
})
}
Как это выглядит с точки зрения потребителя API:
engine = new Engine({path: '/path/to/posts'})
engine.showPostsOnPage()
работает, потому что вы можете зарегистрировать несколько обратных вызовов для обещания, и они запускаются либо после его разрешения, либо, если он уже разрешен, во время присоединения обратного вызова.
Вот как mongoskin
Изменить: Поскольку я написал этот ответ, я влюбился в синтаксис ES6 / 7, поэтому есть и другой пример использования этого. Вы можете использовать его сегодня с babel.
class Engine {
constructor(path) {
this._initialized = this._initialize()
}
async _initialize() {
// actual async constructor logic
}
async showPostsOnPage() {
await this._initialized
// actual body of the method
}
}
Изменить: вы можете использовать этот шаблон изначально с помощью значка узла 7 и --harmony
!