2017-06-14 79 views
0

我有一個非常大的請求,需要15秒才能返回數據。我想在用戶登錄時調用這個請求,以減少他們進入加載數據的路徑所需的時間(他們可以在完成後到達那裏,這會立即向他們顯示數據,或者它可能沒有完成,但只能讓他們在那一刻等待幾秒鐘)。如何避免從後臺返回空數據異步請求角度2-4

因此,當用戶登錄並獲得成功,我爲大數據集的請求:

this.getDataService.getAsyncData(data.LinkToken); // This loads request from data service 

然後我保存這些數據到隨後可供時,返回其本地存儲檢索用戶的土地時,這使得從ngOnOnit(即要求)的路由

getAsyncData(linkToken){ //this is background request that is loading while user navigates through app 
    this.httpC.get(this.baseUrl + "/AccountInfo/Data?linkToken=" + linkToken + "&deliveryTypeId=" + 0 + "&pickupLocationId=" + 0 + "&paymentTypeId=" + 0).map((res:Response) => res.json()).subscribe(res => { 
     this.asycCollection = res; 
     this.globalService.setData(this.asycCollection) //This passes this data to service that stores in local storage 
     console.log(this.asycCollection); 
    }) 
} 

然後該數據可以作爲從組件一個承諾請求加載返回上時路由負載

//This sets local storage with the data 
setData(refillObject:any){ 
    this.refillObj = refillObject; 
    window.localStorage.setItem("refillData", JSON.stringify(this.refillObj)) 
} 
//This gets promise of that background async call 
getData(){ 
    let refillInformation:any = window.localStorage.getItem("refillData"); 

    return new Promise<any>((resolve, reject) => resolve(refillInformation)); 
} 

然後從我的路由組件我想檢索這些數據,但只有當它完成加載數據,否則它會返回null,當然沒有任何工作。因此,如果用戶很快導航到這個頁面,那麼它返回null(因爲請求還沒有完成加載數據)並且爆炸,但是如果用戶在請求完成之後回來,它就按設計工作。

如何在加載完成後等待並獲取數據?請記住,這是從用戶登錄時發出的背景異步請求,我從本地存儲中檢索並且未向REST Svc發出新請求。

組件代碼:

getAsyncRefills(success){ 
    this.globalService.getData().then(data => { //everything below this blows up if the page is loaded before the data request has finished loading to local storage. 
     this.orderData = JSON.parse(data); 
this.currentDeliveryType = this.orderData.DeliveryTypes.find((item) => 
item.DeliveryTypeId == this.orderData.DeliveryTypeId); 
     this.currentPaymentArr = this.currentDeliveryType.PaymentTypes; 
     this.currentPickupLocations = this.currentDeliveryType.PickupLocations; 


     this.setOptions(); 
     this.buildOrders(); 

    }) 

} 
+0

你有使用localStorage的原因嗎?還有爲什麼你在一個應用程序中使用Observables和Promises?我假設緩慢的異步請求 - 以及後來需要來自LocalStorage的數據的代碼是相同的應用程序是否正確? – MikeOne

+0

我試着單獨使用observable或promise,但它仍然加載空值,所以我在添加本地存儲之前只是爲了確保我最終可以獲取對象,但這絕不是一個完成的想法.v它們確實都是相同的應用程序。我目前正在研究使用EventEmitter來訂閱服務中的事件,它在返回時發出檢索到的數據,也有點磕磕絆絆(當數據返回時,訂閱發出的值而不是調用函數)。如果你有一個建議,我很高興與它一起運行。 –

回答

0

我會以下列方式解決這個問題。

我將建立一個服務有責任

  • 火災重查詢在後臺執行
  • 公開爲公共財產的可觀察發出的結果時,的查詢已到達
    • 一旦數據從後端到達,它就會使用發出數據Observable公開爲公共屬性

服務注入,經由依賴注入,到執行的登錄和需要來顯示該數據的組件的組件。

登錄成功後,執行登錄的組件將調用啓動查詢的服務的方法。

需要顯示的數據可以通過服務使用公開爲公共財產可觀察來顯示數據,一旦他們到達的組成部分。有幾種方法可以做到這一點。您可以使用從角的異步管,它允許您直接引用可觀測模板,或者您可以訂閱可觀察,然後用在訂閱邏輯定義的函數,以填補所需的變量。

0

這樣的事情,我不會使用本地存儲,但會使用服務(抱歉沒有一個IDE這樣的代碼可能不是完美的)。

@Injectable() 
export class ExpensiveDataStore { 

    private expensiveData_: ConnectableObservable<ExpensiveThing>; 
    private connection: Subscription; 

    get expensiveData(): Observable<ExpensiveThing> { 
    if(!this.expensiveData_) { 
     throw Error('Must initialize store first!'); 
    } 
    return this.expensiveData_; 
    } 

    initialize() { 
    this.expensiveData_ = this.goFetchExpensiveData().publishLast(); 
    this.connection = this.expensiveData.connect(); 
    } 

    void reset() { 
    this.connection.unsubscribe(); 
    this.connection = this.expensiveData.connect(); 
    } 

} 

在你app.component.ts或一些高級別組件,您可以撥打initialize()。在需要數據的組件中,您可以訂閱expensiveData