合并事件以执行与RxJ和Angular的异步工作

时间:2018-06-18 14:51:26

标签: javascript angular typescript rxjs observable

所以我有一个与模型绑定的复选框:

<mat-checkbox  [(ngModel)]="element[column]" (click)="updateRow(element, $event)"></mat-checkbox>

click事件应该调用服务器并在db中执行写入。

所以,为此,我认为使用concatMap就足够了,因为它在进行下一次调用之前等待,以避免耗尽数据库。

updateRow(row, $event): void {
    Observable.from([{ row: row }])
      .concatMap(i => this._definitionService.updateDefinition(i)  //async work
      .subscribe(result => console.log('row updated'), error => {
        this.snack(error);
      });
  }

问题在于它不会等待,因为每个事件更改都是一个新的调用,执行太多更改会耗尽数据库。

这会是什么解决方案?我想过用这样的fromEvent来绑定事件:

Observable.fromEvent($event.target, 'click')
              .subscribe(i => {
                console.log(i);
              });

但是,它仅在单击复选框上的twice时才有效。

什么是正确的方法?

由于

1 个答案:

答案 0 :(得分:2)

它调用多个请求的原因是每次单击调用updateRow的元素时都会创建Observable.from的新实例。因此concatMap无法帮助您,因为当您点击10次时,它会订阅10个不同的Observable,其中包含10个不同的concatMap s。

实现您想要的最简单方法可能是创建一个中间主题并在每次致电updateRow时将项目推入其中:

const s = new Subject();

s.concatMap(i => this._definitionService.updateDefinition(i))
  .subscribe(
    result => console.log('row updated'),
    error => this.snack(error),
  );

...

updateRow(row, $event): void {
  s.next({ row });
}

现在您只有一个订阅并将多个项目推送到主题s(带next())将按顺序执行。