如何计算未完成的Observable <observable>排放

时间:2016-12-05 20:55:16

标签: rxjs

我有一个发出Observables的Observable。我想发出未完成的Observable排放的当前计数

所以给出了这张大理石图:

--a-----b-------c------
  a-------------------------|
        b----X
                c---------|
___________________
--1-----2----1--2---------1-0

我该怎么做?计算新的排放量是相当容易的,但错误和完成?

2 个答案:

答案 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