簡體   English   中英

如果另一個可觀察對象在RxJS中具有數據,如何忽略所有可觀察對象?

[英]How to ignore all from an observable if the other observable has data in RxJS?

我有兩個觀察對象,一個是從瀏覽器localstorage接收數據,另一個是通過WebAPI數據庫接收數據。

  1. 我要訂閱它們,因此,如果從本地存儲中觀察到的數據中有數據,請不要啟動該數據庫以從數據庫中獲取數據。
  2. 如果從localstorage觀察到的數據沒有任何數據,請調用ajax調用以從WebAPI獲取數據。

在下面的示例中,我應該只獲得20, 40, 60, 80, 100因為第一個可觀察對象具有數據。 第二個可觀察對象未運行,因為第一個可觀察對象開始發出數據。

在此處輸入圖片說明

您可以使用skipWhile並檢查數據並返回true或false。

observableObject.skipWhile((data)=> {
      if(data){
          return false;
      }
});

可觀察到的本地存儲需要某種方式來表示沒有數據。 如果只是“掛起”而從未完成,則可以使用計時器來完成它:

// Use .amb() instead of .race() if your rxjs version is old
const timer = Observable.timer(1000).ignoreElements();
const lsObservable2 = Observable.race(lsObservable, timer);

這將啟動一個計時器,如果可觀察的本地存儲在1秒內未產生值,它將結束流。

如果沒有數據,如果可觀察的本地存儲將自行完成,則可以按原樣使用它:

const lsObservable2 = lsObservable;

在這一點上,我們真的很想使用defaultIfEmpty ,因為它具有您想要的語義。 不幸的是,它僅支持默認值的標量值,而當您想產生不同的可觀察流時。 因此,讓我們編寫我們自己的defaultIfEmpty版本,它使用Observable.defer生成一個新的流。 我們使用defer以便每次有人訂閱時,我們都可以創建一個新的閉包變量( hasValue ),並監視可觀察的源是否為此訂閱生成一個值

Observable.prototype.defaultObservableIfEmpty = function(defaultObservable) {
    const source = this;
    return Observable.defer(() => {
        let hasValue = false;
        // create a deferred observable that will evaluate to
        // defaultObservable if we have not seen any values, or
        // empty observable if we have seen any values.
        const next = Observable.defer(() => hasValue ? Observable.empty() : defaultObservable);

        // now use do() to set hasValue to true if we see a value from
        // the source observable
        const sourceSetsValue = source.do(v => hasValue = true);

        // now we can can just concat this sourceSetsValue
        // with out "next" observable.  When the first observable
        // finishes, it will subscribe to "next", which will then
        // either produce the defaultObservable or an empty observable
        return sourceSetsValue.concat(next);
    });
}

接下來,假設您已將db Observable設置為在實際訂閱之前不發出ajax調用。 這是重要的一步。 同樣,您可以使用類似defer

const dbObservable = Observable.defer(() => makeDbCall());

然后,我們可以像這樣使用您的新運算符:

const data = lsObservable2.defaultObservableIfEmpty(dbObservable);

因此,您的應用程序代碼如下所示(將新運算符添加到庫中之后):

const timer = Observable.timer(1000).ignoreElements();
const lsObservable2 = Observable.race(lsObservable, timer);
const dbObservable = Observable.defer(() => makeDbCall());
const data = lsObservable2.defaultObservableIfEmpty(dbObservable);

暫無
暫無

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

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