Всем доброго дня.
Вопрос в следующем, как вы бы решили задачу с конструктором и асинхронными процессами.
Пример:
class Name {
let self = this;
constructor(data){
this._init(data)
.then(data=>{
self.init = data;
})
.catch(console.error);
}
_init(data) {
return new Promise((resolve, reject) => {
// искусственно создаем задержку, эмцлируя веб запрос:
setTimeout(resolve, 2000, data);
//resolve(data);
})
run(data) {
rerurn data / this.init.
}
run2(data){
let self = this;
return new Promise((resolve, reject) => {
resolve(data / self.init);
})
}
}
В примере выше мы при инициализации делаем асинхронную задачу, предположим что она будет занимать какое-то время (запрос по http или чего , не суть)
Как пример:
let name = new Name(2);
console.log(name.run(6));
//или
name.run2(6).then(console.log).catch(console.error);
Ожидаем получить 3, но можем и не получить, так как this.init может быть еще не получено и конструктор еще работает.
Кто как с этим борется?
У меня на ум, да и в практике реализован костыль, переменная - триггер, которая символизирует, что конструктор отработал и если триггер не установлен, делается задержка, но мне не нравится такой подход, может кто подскажет более изящное решение?
Пока нашел следующие решения:
1. Через фабрику:
class Engine {
constructor(data) {
this.data = data;
}
static makeEngine(pathToData) {
return new Promise((resolve, reject) => {
getData(pathToData).then(data => {
resolve(new Engine(data))
}).catch(reject);
};
}
}
Плюсом вижу, что объект будет создан только тогда, когда выполнится вся вермешляндия, минусом то, что объект будет результатом промиса и опять либо в генераторе работать с ним для удобства, либо в async. Ну или при жестком троллинге всего этого добра писать основной код почле тааймаута.
2. Через специфичный конструктор , мне идея понравилась, но надо потестировать, плюс использовать 7 ноду с хармони:
class Engine {
constructor(path) {
this.initialization = (async () => {
this.resultOfAsyncOp = await doSomethingAsync(path)
})()
}
async showPostsOnPage() {
await this.initialization
// actual body of the method
}
}