gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 17:51:33 25 4
gpt4 key购买 nike

我有两个 observable,一个从浏览器 localstorage 接收数据,另一个通过 WebAPIdatabase 接收数据。

  1. 我想订阅它们,这样如果来自 localstorage 的可观察对象有数据,不要启动从数据库 获取数据的对象。
  2. 如果 localstorage 中的 observable 没有任何数据,调用 ajax 调用以从 WebAPI 获取数据。

在下面的例子中,我应该只得到 20, 40, 60, 80, 100 因为第一个 observable 有数据。第二个 Observable 没有运行,因为第一个 Observable 开始发射数据。

enter image description here

最佳答案

本地存储 observable 需要某种方式来表示没有数据。如果它只是“挂起”并且永远不会完成,那么您可以使用计时器来完成它:

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

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

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

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

关于javascript - 如果另一个可观察对象在 RxJS 中有数据,如何忽略所有可观察对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43151520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com