有没有一种好方法可以检查是否完成Observable在那个确切的时间是空的?
let cache = new ReplaySubject<number>(1);
...
// Here I want to know if 'cache' still empty or not. And, for example, fill it with initial value.
cache.isEmpty().subscribe(isEmpty => {
if (isEmpty) {
console.log("I want to be here!!!");
cache.next(0);
}
});
// but that code does not work until cache.complete()
答案 0 :(得分:2)
您可以使用takeUntil()
:
Observable.of(true)
.takeUntil(cache)
.do(isEmpty => {
if (isEmpty) {
console.log("I want to be here!!!");
cache.next(0);
}
})
.subscribe();
然而,这只会运作一次。
另一种方式是&#34; null&#34;缓存并使用BehaviorSubject
:
let cache = new BehaviorSubject<number>(null as any);
...
cache
.do(content => {
if (content == null) {
console.log("I want to be here!!!");
cache.next(0);
}
})
.subscribe();
当然,您可以立即使用默认值初始化缓存。
答案 1 :(得分:2)
实际上,它并不那么简单,而且接受的答案并不是非常普遍。您想在此特定时间点检查ReplaySubject
是否为空。
但是,如果您想要使其真正与ReplaySubject
兼容,则还需要考虑&#34;时间的windowTime
参数对于通过此对象的每个值,实时&#34; 。这意味着您的cache
是否为空会及时更改。
ReplaySubject
方法_trimBufferThenGetEvents
可以满足您的需求。不幸的是,这种方法是私密的,所以你需要做一点&#34; hack&#34;在JavaScript中并直接扩展其prototype
。
import { ReplaySubject } from 'rxjs';
// Tell the compiler there's a isNowEmpty() method
declare module "rxjs/ReplaySubject" {
interface ReplaySubject<T> {
isNowEmpty(): boolean;
}
}
ReplaySubject.prototype['isNowEmpty'] = function() {
let events = this._trimBufferThenGetEvents();
return events.length > 0;
};
然后使用此ReplaySubject
很简单:
let s = new ReplaySubject<number>(1, 100);
s.next(3);
console.log(s.isNowEmpty());
s.next(4);
setTimeout(() => {
s.next(5);
s.subscribe(val => console.log('cached:', val));
console.log(s.isNowEmpty());
}, 200);
setTimeout(() => {
console.log(s.isNowEmpty());
}, 400);
请注意,对isNowEmpty()
的某些调用会返回true
,而其他调用会返回false
。例如,最后一个返回false
,因为该值在此期间无效。
此示例打印:
true
cached: 5
true
false
答案 2 :(得分:1)
您可以使用.scan()
累积您的计数,并将其映射到布尔值是否非零。 (对于种子值,它需要第二个参数,使其以0开头,因此它始终反映当前计数。)
我还添加了.filter()而不是if语句,以使其更清晰:
let cache = new ReplaySubject<number>(1);
cache
.map((object: T) => 1)
.scan((count: number, incoming: number) => count + incoming, 0)
.map((sum) => sum == 0)
.filter((isEmpty: boolean) => isEmpty)
.subscribe((isEmpty: boolean) => {
console.log("I want to be here!!!");
cache.next(0);
});
答案 3 :(得分:0)
let cache = new ReplaySubject<number>(1);
isEmpty$ = cache.pipe(mapTo(false), startWith(true));
这说:
false
。 (因为发射后它不为空)true
开始(因为这意味着它是空的)