Javascript 如果另一个可观察对象在RxJS中有数据,如何忽略该可观察对象的所有数据?

Javascript 如果另一个可观察对象在RxJS中有数据,如何忽略该可观察对象的所有数据?,javascript,rxjs,observable,Javascript,Rxjs,Observable,我有两个观察对象,一个从浏览器localstorage接收数据,另一个从数据库通过WebAPI接收数据 我想订阅它们,因此如果本地存储中的可观察对象有数据,不要启动从数据库获取数据的可观察对象 如果从本地存储中观察到的数据没有任何 数据,调用ajax调用从WebAPI获取数据 在下面的示例中,我应该只得到20,40,60,80,100,因为第一个可观察对象有数据。第二个可观察对象没有运行,因为第一个可观察对象开始发送数据 您可以使用skipWhile检查数据并返回true或false obser

我有两个观察对象,一个从浏览器localstorage接收数据,另一个从数据库通过WebAPI接收数据

  • 我想订阅它们,因此如果本地存储中的可观察对象有数据,不要启动从数据库获取数据的可观察对象
  • 如果从本地存储中观察到的数据没有任何 数据,调用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);
    
    这将启动一个计时器,如果本地存储observable在1s内没有生成值,它将结束流

    如果您的本地存储observable将在没有数据的情况下自行完成,则您可以按原样使用它:

    const lsObservable2 = lsObservable;
    
    在这一点上,我们非常希望使用,因为它具有您想要的语义。不幸的是,当您希望生成不同的可观察流时,它只支持默认值的标量值。因此,让我们编写自己版本的
    defaultIfEmpty
    ,它使用生成一个新流。我们使用
    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调用。这是重要的一步。同样,您可以使用类似于
    延迟

    const dbObservable = Observable.defer(() => makeDbCall());
    
    然后我们可以像这样使用您的新操作员:

    const data = lsObservable2.defaultObservableIfEmpty(dbObservable);
    
    因此,您的应用程序代码如下所示(将新操作符添加到库中后):


    您希望本地存储器可观察到多少值?大概只有一个;在这种情况下,这个问题是这个问题的翻版:我想要这个问题中提到的所有可观测值。它们是
    20,40,60,80100
    。您的大理石图并不代表上面提出的问题。在图中,两个流同时开始,并且您已经声明将忽略底部流。然而,在上面的问题中,您声明如果localstorage observable具有数据,则不会启动ajax observable。此外,您没有定义“有数据”的含义。localstorage observable是否已完成?不清楚你在问什么。大理石图只是说明有两条流的指南。如果第一个可观察/流有数据,则不应启动第二个ajax可观察/流。localstorage observable可以或不能包含数据。它更像是本地缓存数据。当应用程序启动时,将不会有任何数据。ajax observable从服务器引入的数据将写入本地存储。从下一次开始,应用程序将从本地存储可观测数据中获取数据。这将仅适用于一个可观测数据。这个问题中有两个观察到的现象。你能详细说明一下吗?你可以看看这个。我认为这两个问题都试图解决一个类似的问题。但在我的问题中,如果缓存已经有数据,我想取消或不启动promise/ajax调用。
    const timer = Observable.timer(1000).ignoreElements();
    const lsObservable2 = Observable.race(lsObservable, timer);
    const dbObservable = Observable.defer(() => makeDbCall());
    const data = lsObservable2.defaultObservableIfEmpty(dbObservable);