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

编程入门 行业动态 更新时间:2024-10-17 19:20:59
本文介绍了如果另一个可观察对象在RxJS中有数据,如何忽略所有可观察对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

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

I have two observables, one receives data from the browser localstorage and the other is from the database through WebAPI.

  • 我要订阅它们,因此,如果 localstorage 中的可观察对象具有数据,请不要启动该对象以从数据库中获取数据.
  • 如果 localstorage 中的可观测对象没有任何内容 数据,请调用 ajax 调用以从 WebAPI 获取数据.
  • I want to subscribe to them so if the observable from the localstorage has data, don't initiate the one to get the data from the database.
  • If the observable from the localstorage does not have any data, invoke the ajax call to get the data from the WebAPI.
  • 在下面的示例中,我应该只获取20, 40, 60, 80, 100,因为第一个可观察对象具有数据.第二个可观察对象未运行,因为第一个可观察对象开始发出数据.

    In the following example, I should get only 20, 40, 60, 80, 100 because the first observable has data. The second observable did not run because the first observable started emitting data.

    推荐答案

    可观察到的本地存储需要某种方式来表示没有数据.如果只是挂起"而从未完成,那么您可以使用计时器来完成它:

    The local storage observable needs some way to signal that there is no data. If it just "hangs" and never completes, then you might use a timer to complete it:

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

    这将启动一个计时器,如果可观察到的本地存储在1秒内未产生值,则它将结束流.

    This will start a timer and if the local storage observable does not produce a value within 1s, it will end the stream.

    如果没有数据,则可观察的本地存储将自行完成,那么您可以按原样使用它:

    If your local storage observable will complete on its own if there is no data, then you can use it as is:

    const lsObservable2 = lsObservable;

    在这一点上,我们真的很想使用 defaultIfEmpty ,因为它具有您想要的语义.不幸的是,它只支持默认值的标量值,而当您想产生不同的可观察流时.因此,让我们编写我们自己的defaultIfEmpty版本,它使用 Observable.defer .我们使用defer,以便每次有人订阅时,我们都可以创建一个新的闭包变量(hasValue),并监视可观察到的源是否为此订阅生成了一个值

    At this point, we'd really like to use defaultIfEmpty, because that has the semantics you want. Unfortunately it only supports a scalar value for the default, when instead you want to yield a different observable stream. So lets write our own version of defaultIfEmpty which produces a new stream using Observable.defer. We use defer so that each time someone subscribes, we can create a new closure variable (hasValue) and monitor whether or not the source observable produces a value for this subscription

    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); }); }

    接下来,让我们假设您已将数据库Observable设置为在实际订阅之前不发出ajax调用.这是重要的一步.同样,您可以使用defer:

    Next, let's assume you've setup your db Observable to not issue the ajax call until it is actually subscribed. This is an important step. Again you can use something like defer:

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

    然后我们可以像这样使用您的新运算符:

    Then we can use your new operator like so:

    const data = lsObservable2.defaultObservableIfEmpty(dbObservable);

    因此,您的应用程序代码如下所示(将新运算符添加到库中之后):

    So your application code looks like this (once you've added the new operator to your library):

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

    更多推荐

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

    本文发布于:2023-11-27 23:29:22,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1640033.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:对象   中有   数据   RxJS

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!