Angular rxjs如何观察未完成的观察集合

Angular rxjs如何观察未完成的观察集合,angular,rxjs,Angular,Rxjs,我有一组可观察对象(typescriptObservable),每个可观察对象发出多次,然后完成,我想在它们完成时将它们从集合中删除,但当它们仍然处于活动状态时,我需要从中了解最新的值。如果场景没有改变,我会有这样的场景: function all(inputs: Observable<boolean>[]) { return combineLatest([...inputs]).pipe(map((values) => values.every(v=>v))); }

我有一组可观察对象(typescript
Observable
),每个可观察对象发出多次,然后完成,我想在它们完成时将它们从集合中删除,但当它们仍然处于活动状态时,我需要从中了解最新的值。如果场景没有改变,我会有这样的场景:

function all(inputs: Observable<boolean>[]) {
  return combineLatest([...inputs]).pipe(map((values) => values.every(v=>v)));
}
function all(输入:可观察[]){
返回combineLatest([…inputs]).pipe(map((values)=>values.every(v=>v));
}
但我需要能够注册新的观测值,并在它们完成时从输入列表中删除它们

class AssentService {
  all(): Observable<boolean> { /* ??? */ }

  register(input: Observable<boolean>) { /* ??? */ }
}
类资产服务{
all():可观测的{/*???*/}
寄存器(输入:可观察){/*???*/}
}
all
只会被调用一次(可能在任何寄存器调用之前),但是
register
可以被调用多次,并且需要添加该输入,直到完成(最终我需要的不仅仅是
all
,但我非常确定,一旦我得到这一个,我就可以找出其余的那些).

您可以使用
mergeAll()
将高阶观测值合并到链中:

subject
  .pipe(
    mergeAll(),
  )
  .subscribe({
    next: console.log,
    complete: () => console.log('completed')
  });

...

subject.next(timer(1000));
subject.next(timer(1000));
subject.complete();
只有在所有嵌套的可观察对象完成之后以及源
subject
完成时,才会调用complete处理程序。您不需要删除已完成的观测值,因为它们会自动取消订阅


实时演示:

这是一个自定义操作符,它使用映射实现CombineTest,每次有流发出时,只发出当前正在运行的流的数组

这是一个高阶运算符,因此您可以像使用
mergeAll()
concatAll()
一样使用它,因为它需要一个观察流

combineLatestAll(){
  return stream$ => defer(() => {
    const register = new Map<number, any>();
    return stream$.pipe(
      mergeMap((inner$: Observable<any>, index: number) => inner$.pipe(
        finalize(() => register.delete(index)),
        map(payload => {
          register.set(index, payload);
          return Array.from(register.values());
        })
      ))
    )
  })
}

这就是我一直在寻找的东西,我不知道如何找到。谢谢。我需要在它们完成后删除它们的原因是因为我只需要关注“活着的”主题。就可能与当今世界相关的术语而言,我传递给
register
的每一个主题都是一个选民,在我要求选举时都可以投票,但如果他们当时死了,我不在乎他们的投票。
class AssentService {
  private _registered$ = new Subject<Observable<boolean>>();

  all(): Observable<boolean[]> {
    return this._registered$.pipe(
      combineLatestAll()
    )
  }

  register(input: Observable<boolean>) {
    this._registered$.next(input);
  }
}
class AssentService {
  private _registered$ = new Subject<Observable<boolean>>();
  private _cashed$ = _registered$.pipe(
    combineLatestAll(),
    shareReplay(1)
  );

  /*** init(){ ***/
    this._cashed$.subscibe();
  /*** } ***/    

  all(): Observable<boolean[]> {
    return this.cashed$;
  }

  register(input: Observable<boolean>) {
    this._registered$.next(input);
  }
}