簡體   English   中英

Rxjs只執行一次concatMap

[英]Rxjs execute concatMap only once

我有兩個Observable, getUsergetUserAvatar 它們都發出兩個值 - 使用BehaviorSubject立即緩存,並在網絡請求后立即緩存。

現在代碼以這種方式工作:

1)發送請求以獲取用戶並立即發出緩存用戶

2)緩存用戶發出后,代碼進入concatMap,並首次執行getUserAvatar

3)getUserAvatar向服務器發送請求並立即發出緩存的userAvatar

4)一切都已完成,緩存的用戶返回了緩存的頭像

5)一段時間后,真實用戶返回並且getUser再次發出值

6) 在這一步,我想第二次阻止調用concatMap ,因為服務器請求已在進行中,我只想返回'USER LOADED。

sendGetRequest('/user/').pipe(
        concatMap(() => {
            // HERE, after user data loaded, I have url for his avatar
            return sendGetRequest('/avatar/').pipe();
        }),
        map(() => {
            return 'USER LOADED';
        })
    )

服務器請求代碼

sendGetRequest(url: string, ignoreCache?: boolean): any {

    let responseSubj = new Subject();

    const cachedData = this.cache.getItemForUrl(url);
    const cacheAllowed = cachedData && !ignoreCache;
    if (cacheAllowed) {
        responseSubj = new BehaviorSubject(cachedData);
    }

    const getFromServer = this.http.get(environment.API_SERVER_URL + url, this.addAuth()).pipe(
        filter((res: any) => {

            if (cacheAllowed && JSON.stringify(cachedData) === JSON.stringify(res)) {
                responseSubj.complete();
                return false;
            }

            this.cache.setItemForUrl(url, res).then(() => {
                responseSubj.complete();
            });
            return true;
        }),
        catchError((error, caught) => {
            console.log('ERROR FROM GET REQUEST', error);
            return throwError(error);
        })
    );


    return merge(responseSubj, getFromServer);
}

所以,我認為這就是你所追求的:

https://stackblitz.com/edit/angular-2kaawf

因此,正如您所看到的,我沒有聲明任何主題來獲取緩存的結果。 我不是說你不應該使用主題。 在這種情況下你只是不需要它們。 我添加了一個清除緩存和重新加載按鈕,以說明您可以使用的主題。

如果您重新加載頁面,您將看到以前使用的數據被重用。 但是,當您清除緩存時,緩存的數據將消失,重新加載后您將看到“null”。

此代碼將按預期工作。 但是,如果您在用戶$ observable上有2個訂閱,則會得到一些意外結果。 要解決這些問題,請查看shareReplay運算符;)

您應該使用exhaustMap而不是concatMap

exhaustMap忽略其他值,直到observable完成。

例如,

fromEvent(this.saveButton.nativeElement, 'click')
.pipe(
    exhaustMap(() => this.saveCourse(this.form.value))
)
.subscribe();

如果我們現在點擊“保存”連續說5次,我們可以看到,我們在保存請求仍在進行時所做的點擊會被忽略,正如預期的那樣!

示例來自angularuniveristy博客。

排氣圖的詳細說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM