2017-08-24 52 views
0

使用RxJs 5角4RxJs:共享使用異步可觀察/等待

我想分享一個可觀察的,這樣我只能讓1個Http請求,我也希望讓我去等待來電當我請求它的結果。我有以下代碼:

export class DataService { 
    constructor(public http: HttpClient) { 
     this.getObservable(); 
    } 

    public observable; 

    public getObservable() { 
     const url = "api/getData"; 
     this.observable = this.http.get(`${this.baseUrl}${url}`).share() 
    } 

    public async hasData(data: DataEnum) {   
     const result = await this.observable.toPromise(); 
     return result.filter(x => x === data).length > 0; 
    } 
} 

但是,許多調用hasData導致了許多調用我們的API端點。我假設我已將observable設置爲共享的觀測值,當我打電話給.toPromise()時,它只會獲取緩存的值並將其作爲承諾,我可以await

這是應該如何工作?

+0

你爲什麼要這麼做?我們可以用更好的技術來幫助你? – Microsmsm

+0

如果您已經使用承諾,是否有某些事情阻止您保存承諾?這將是非常簡單的。共享運營商無法按照您的預期工作。 – estus

+0

@Microsmsm代碼被簡化了:)當應用程序加載時,我需要知道在哪裏指導用戶 - 因此需要等待結果。該數據還包含HTML模板中請求的其他一些信息,因此我們會收到很多電話,我想分享。 – user917170

回答

1

你的代碼對我來說似乎過於複雜。我可能會做這樣的事情:

private data = null; 

getData():Observable<> { 
    // if data is already available, return it immediately 
    if (this.data) return Observable.of(this.data); 

    // else, fetch from the server and cache result 
    return this.http.get(url).do(data => this.data=data) 
} 

所以每當你想要的數據,你只是做:

this.getData().subscribe(
    data => console.log(data); 
) 

爲了確保數據到達之前,你不會打電話給你的API端點多次,你有幾個選擇。

  • 調查data resolvers - 這些將不會初始化您的組件,直到數據到達。在ngOnInit數據將準備好同步,所以沒有多次呼叫服務器的風險。

  • 或者,您可以隱藏視圖,直到數據準備好與*ngIf="data",因此用戶不會多次單擊按鈕。

+0

這樣做的問題是'數據'是異步設置的,所以如果我快速連續調用兩次'getData()'並且api調用需要一些時間,它將被調用兩次。 – user917170

+0

@ user917170我添加了一點到我的答案。 – BeetleJuice

+0

好的我認爲數據解析器實際上是問題的正確解決方案,在我的問題中不一定清楚,但是我們希望阻止加載路由,直到服務調用返回。謝謝! – user917170

1

由於如何share作品,observabletoPromise重新訂閱,部份產生新的要求。

承諾已經提供了緩存行爲。考慮到許諾已經在服務API中使用,它們可以獨家使用:

constructor(public http: HttpClient) { 
    this.getPromise(); 
} 

public promise; 

public getPromise() { 
    const url = "api/getData"; 
    this.promise = this.http.get(`${this.baseUrl}${url}`).toPromise() 
} 

public async hasData(data: DataEnum) {   
    const result = await this.promise; 
    return result.filter(x => x === data).length > 0; 
} 
+0

感謝您的回答,這可能會奏效,但實際上路由守衛數據解析器是修復它的'角度'方法。 – user917170