2

我有一个应用程序,每次用户选择表中的一行时都会刷新一个数据网格表。为了简单起见,我有一个示例代码:

子组件.ts

public jsonData = {...} //api request

this.rowSelectedEvent.subscribe(() => {
  this.refreshData(this.jsonData) 
})

function refreshData(jsonData){
  this.httpService.post(`${environment.BASE_URL}/api`, jsonData.payload).subscribe(
    result => {
      this.resultData = result.data
    }, 
    err => {
      console.error(err)
    }
  )
}

rowSelectedEvent用户单击表格的一行时,会在 HTML 中触发。这将是一个例子:

app.component.html

<table>
  <row (click)="notifyRowSelected"></row>
</table>

app.component.ts

@Output() rowSelectedEvent: EventEmitter<string> = new EventEmitter();

[...]

function notifyRowSelected(){
  this.rowSelectedEvent.emit()
}

此代码工作正常,接收带有新数据的 API 响应,服务器端进行计算并返回新值大约持续 4-5 秒。当用户重复或在短时间内单击几行时出现问题,因为应用程序发疯并多次刷新数据而不是一次(最后一次)。我尝试使用unsubscribe(),但后来我无法再次订阅,因此功能丢失。我也尝试过switchMap(),但由于某种原因,当我调试代码时它没有进入它。

这个想法是在用户单击新行时停止挂起的进程,让最后一次单击成为进行计算并接收响应的那个。有什么建议吗?

4

1 回答 1

4

你可以使用 rxjs 的力量来处理它

private makeCall(data) {
  return this.http.post(...);
}
this.rowSelectedEvent.pipe(
   map(() => this.jsonData),
   distinctUntilChanged(), // to skip the same events in a row
   switchMap((data) => this.makeCall(data)),
).subscribe((result) => this.resultData = result.data)

所有需要的权力都在于switchMap操作员。每当有新事件出现时,它都会取消先前的订阅(如果尚未完成,您将在网络选项卡中看到已取消的红色请求)并且订阅内的处理程序将仅接收最后一个事件

于 2019-12-11T13:50:22.503 回答