我有两个可观察对象,一个从浏览器本地存储接收数据,另一个通过WebAPI从数据库接收数据。
- 我想订阅它们,因此如果本地存储中的可观察对象有数据,则不要启动从数据库获取数据的观察对象。
- 如果 localstorage 中的可观察对象没有任何 data,调用ajax调用从WebAPI获取数据。
在下面的示例中,我应该只得到 20, 40, 60, 80, 100
因为第一个可观察值有数据。第二个可观察对象未运行,因为第一个可观察对象开始发出数据。
最佳答案
本地存储可观察对象需要某种方式来表明没有数据。如果它只是“挂起”并且从未完成,那么您可以使用计时器来完成它:
// Use .amb() instead of .race() if your rxjs version is old
const timer = Observable.timer(1000).ignoreElements();
const lsObservable2 = Observable.race(lsObservable, timer);
这将启动一个计时器,如果本地存储 observable 在 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);
关于javascript - 如果另一个可观察量在 RxJS 中有数据,如何忽略一个可观察量中的所有数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43151520/