我有一个发出Observables的Observable。我想发出未完成的Observable排放的当前计数
所以给出了这张大理石图:
--a-----b-------c------
a-------------------------|
b----X
c---------|
___________________
--1-----2----1--2---------1-0
我该怎么做?计算新的排放量是相当容易的,但错误和完成?
答案 0 :(得分:2)
您可以创建一个主题,供所有其他可观察者使用,以告知他们当前的状态。然后,您可以使用此主题将状态减少为当前活动的Observable的数量。
请参阅此jsbin example。
const meta$ = new Rx.Subject();
// Create some streams that we can observe.
const stream1$ = Rx.Observable.interval(300);
const stream2$ = Rx.Observable.timer(1000)
.switchMap(() => Rx.Observable.interval(500).startWith(0))
.take(10);
const stream3$ = Rx.Observable.timer(1500)
.switchMap(() => Rx.Observable.interval(500).startWith(0))
.take(2);
stream1$.subscribe(
next => meta$.next({ stream1: true }),
() => meta$.next({ stream1: false }),
() => meta$.next({ stream1: false })
);
stream2$.subscribe(
next => meta$.next({ stream2: true }),
() => meta$.next({ stream2: false }),
() => meta$.next({ stream2: false })
);
stream3$.subscribe(
next => meta$.next({ stream3: true }),
() => meta$.next({ stream3: false }),
() => meta$.next({ stream3: false })
);
meta$
.scan((state, next) => {
return Object.assign({}, state, next);
})
.map(obj => {
return Object.keys(obj)
.map(key => +obj[key])
.reduce((acc, x) => acc + x, 0)
})
.take(50) // don't create endless loop
.timestamp()
.subscribe(x => console.log(x));
答案 1 :(得分:1)
根据@chromate和其他answers on SO的建议,我想出了以下解决方案:
Rx.Observable.prototype.streamLifecycleCounter = function () {
const _this = this; // reference to our upstream observable
return Rx.Observable.create(observer => {
observer.onNext(1);
return _this.subscribe(
() => {}, /* not interested in the actual values */
err => {
observer.onNext(-1);
observer.onCompleted();
},
() => {
observer.onNext(-1);
observer.onCompleted();
}
);
});
};
const scheduler = new Rx.TestScheduler();
const results = scheduler.startScheduler(
() => {
return Rx.Observable.range(1,5)
.map(i => Rx.Observable.just(i).delay(i * 1000, scheduler))
.flatMap(obs => obs.streamLifecycleCounter())
.startWith(0)
.scan((acc, curr) => acc += curr, 0)
.do(console.log);
},
{ disposed: 15000 }
);
这会产生以下控制台输出:
0 1 2 3 4 5 4 3 2 1 0