订阅者可观察到RxJS完成后执行功能

时间:2020-07-20 10:48:20

标签: angular rxjs rxjs-observables rxjs-pipeable-operators

在RxJS中,对于给定可观察对象的所有订阅均已执行后,我需要执行一些代码。我需要在每个触发的next通知发出之后以及所有订阅者功能完成之后(不仅在可观察对象完成时一次),还要执行此操作。

换句话说,我需要一个像tap()这样的运算符,它在所有订阅者都执行完之后运行。有办法吗?

示例:

我正在开发一个UI小部件库(例如,对角材料已经提供的那些扩展的某种扩展)。这些小部件之一必须完成以下任务:

  1. 提供一个按钮,
  2. 单击按钮时,在按钮内显示一个微调器,
  3. 让控件让谁使用窗口小部件执行某些工作(例如,在数据库内部编写),
  4. 完成工作后,将微调器隐藏在按钮内。

假设使用Observable实现以上目标,我希望能够做类似的事情(如果有帮助,我可以在Angular 10项目中使用打字稿):

const eventEmitter = new EventEmitter<any>();

const observable = eventEmitter.asObservable().pipe(
  tap(() => ...show the spinner...), // OK, no problem
  someOperator(() => ...hide the spinner when all subscriber functions complete...) // Which operator can I use?
);

observable.subscribe(() => console.log('First consumer'));
observable.subscribe(() => console.log('Second consumer'));

eventEmitter.emit('DATA');

单击按钮时所需的事件顺序为:

  1. 事件以'DATA'作为有效载荷发出,
  2. 显示按钮内的微调器,
  3. 'First consumer'已登录到控制台,
  4. 'Second consumer'已登录到控制台,
  5. 按钮内的微调器已删除。

奖金问题:在执行每个订户后如何运行一些代码?

1 个答案:

答案 0 :(得分:0)

如果我理解正确,则应将此功能包装在单独的组件中或作为指令包装。您需要在模板中侦听以显示和隐藏微调框的“可观察的”是由BehaviorSubject控制的加载状态。因此,该按钮的模板应如下所示:

<button (click)="buttonClicked()">New UI Element <span *ngIf="loading | async">Spinner</span></button>

您可以在模板中使用事件绑定来触发负责按钮单击逻辑的功能。

使用BehaviorSubject,组件逻辑应该看起来像这样。

loading: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

...

buttonClicked() {
    this.loading.next(true);

    // Perform some logic

    this.loading.next(false);
}