2016-05-20 3 views
2

Примера:Асинхронная загрузка данных в конструкторе класса

var readBackend = function(){ 
    var deferred = q.defer(); 
    readData().then(function(data) { 
     deferred.resolve(data); 
     }) 
    return deferred.promise; 
} 

class Test { 
    constructor(){ 
     readBackend().then(function(data) { 
      this.importantData = data; 
     }) 
    } 

    someFunc() { 
     //iterate over important data, but important data is defined 
     //promise didnt resolved yet 
    } 

} 

var test = new Test(); 
test.someFunc(); //throws exception! 

Есть ли способ, чтобы гарантировать, что свойства объекта инициируется конструктора, когда я называю someFunc?

Единственный способ, который приходит на ум создает init функцию, которая будет возвращать обещание, но потом, каждый раз я использую мой класс, я бы полагаться на функцию инициализации для правильной работы

+0

[Не выполнять асинхронную загрузку данных в свой конструктор] (http://stackoverflow.com/q/24398699/1048572). – Bergi

ответ

5

Есть ли способ чтобы гарантировать, что свойства объекта инициируются конструктором, когда я вызываю someFunc?

Непревзойденный код. Вы не можете, чтобы ваш конструктор выполнял асинхронные операции и ожидал, что ваши синхронные методы будут работать.


Я вижу два возможных решения:

1. иметь статический метод, который загружает данные и возвращает новый экземпляр вашего класса:

class Test { 
    static createFromBackend() { 
     return readBackend().then(data => new Test(data)); 
    } 

    constructor(data){ 
     this.importantData = data; 
    } 

    someFunc() { 
     // iterate over important data 
    } 
} 

Test.createFromBackend().then(test => { 
    test.someFunc(); 
}); 

Это гарантирует, что данные доступны когда экземпляр создан, и вы можете сохранить API класса синхронным.

2. Храните обещание на объекте:

class Test { 
    constructor(){ 
     this.importantData = readBackend(); 
    } 

    someFunc() { 
     this.importantData.then(data => { 
     // iterate over important data 
     }); 
    } 
} 

Конечно, если someFunc должна возвращать что-то, что потребует его вернуть обещание, а также. То есть API вашего класса теперь асинхронен.

Смежные вопросы