2016-09-27 61 views
0

基本上我調用了返回Promises的不同的SQL存儲過程。通常這些將以隨機順序開始/結束,因爲它們是異步的。我需要控制每個過程被調用的順序。注意Promise完成,然後執行下一個Promise。可觀察vs承諾?

我對callCustomerIUD承諾使用.then()試過,但this._dataService.customerIUD(...).then(...)不運行,直到後callCustFieldIUD(),所以customerFieldIUD得到this.keyundefined

saveChanges(record) { 
    this.callCustomerIUD(record); 
    this.callCustFieldIUD(); 
} 

callCustomerIUD(record): Promise<any>{ 
    return this._dataService 
     .customerIUD(...) 
     .then(data => { 
      //THIS KEY IS NEEDED FOR customerFieldIUD 
      this.key = data[data.length-1].CustomerKey; 
     }, error => { 
      console.log(error); 
     }); 
} 

callCustFieldIUD() : Promise<any>{ 
    //USES KEY FROM customerIUD 
    this.fillCustomerField(this.key); 
    return this._dataService.customerFieldIUD(...); 
} 

我已經考慮了Observables,我可以在這種情況下使用它們嗎? 這是我的data.service.ts方法參考上面。這些應該是可觀察的而不是承諾?

customerIUD(data: any) : Promise<any>{ 
    return this.fooHttp 
     .postData(...); 
} 

customerFieldIUD(data: any) : Promise<any>{ 
    return this.fooHttp 
     .postData(...); 
} 
+1

一般來說可觀測量可以做到這一點ES6承諾做的工作。我不確定您的方法會發生什麼,但可能RxJS操作員可能會有所幫助。 – estus

+0

我是新來的observables。你認爲如果我在這裏將'Promise'類型改爲'Observable',我可以使用rxjs操作符來觀察Observable嗎? – jhhoff02

+1

目前還不清楚'fooHttp'是你自己還是第三方服務。如果它返回promise,則應該用'fromPromise'運算符將它們轉換爲observable,或者應該修改整個'fooHttp'服務以使用observables。 – estus

回答

1

是,觀測會在這種情況下

saveChanges(record) { 
    this.callCustomerIUD(record).take(1).subscribe((data: any) => { 
    // Observables can be subscribed to, like a .then() on a promise 
    // data will be the response from the http call 
    this.callCustFieldIUD(data).take(1).subscribe(); 
    }); 
} 

callCustomerIUD(record): Observable<any>{ 
    return this._dataService.customerIUD(...) 
} 

callCustFieldIUD(data: any) : Observable<any>{ 
    //USES KEY FROM customerIUD 
    this.fillCustomerField(this.key); 
    return this._dataService.customerFieldIUD(...); 
} 

而且在服務

customerIUD(data: any) : Observable<any>{ 
    return this.fooHttp.postData(...).map((res: any) => { 
    return res.json(); 
    }); 
} 

customerFieldIUD(data: any) : Observable<any>{ 
    return this.fooHttp.postData(...).map((res: any) => { 
    return res.json(); 
    }); 
} 

是巨大的,因爲callCustFieldIUD()函數被調用的內部認購()來callCustomerIUD()函數返回的observable,直到數據存在纔會執行。

(這可能不是你所需要的確切的代碼。我不知道什麼時候已經發生,但通過訂閱可觀察,你就可以更加嚴格,當函數被調用)

希望這有助於

_______________編輯_________________________

我相信你可以的承諾也實現這一點,只需要輕微的重構

saveChanges(record) { 
    this.callCustomerIUD(record); 
} 

callCustomerIUD(record): Promise<any>{ 
    return this._dataService 
     .customerIUD(...) 
     .then(data => { 
      // Instead of setting an instance var here, pass it in to the callCustFieldIUD() function 
      this.callCustFieldIUD(data[data.length-1].CustomerKey); 
     }, error => { 
      console.log(error); 
     }); 
} 

callCustFieldIUD(customerKey: any) : Promise<any>{ 
    //USES KEY FROM customerIUD 
    this.fillCustomerField(this.key); 
    return this._dataService.customerFieldIUD(...); 
} 
+1

@ jhhoff02我認爲還有一種基於承諾的解決方案。看到我上面的編輯 –

+0

我使用了Observables的想法以及'fromPromise()'如上面建議的estus – jhhoff02

1

您的第一個版本無法正常工作的原因是因爲您的程序在http請求正在進行時繼續執行。一個解決方案是強制執行callCustFieldIUD,在它需要的密鑰被設置後發生。如果您使用Observables,則會出現同樣的問題並以類似的方式解決。

你應該能夠做到:

saveChanges(record) { 
    this.callCustomerIUD(record); 
} 

callCustomerIUD(record): Promise<any>{ 
return this._dataService 
    .customerIUD(...) 
    .then(data => { 
     //THIS KEY IS NEEDED FOR customerFieldIUD 
     this.key = data[data.length-1].CustomerKey; 
     // Call the method you need to execute after the key is guaranteed 
     // to be set 
     this.callCustFieldIUD(); 
    }, error => { 
     console.log(error); 
    }); 
}