0

组件控制器:

private updateSplitScreenService = () => {
    this.splitScreenService.emitNewState(this.products);
    this.splitScreenService.emitNewState(this.stores);
};

拆分屏幕服务:


// emitNewState is called multiple times in quick succession but
// we want to only fire one API request and return the observable back 
// to the component
public emitNewState = (items: Products[] | Stores[]): void => {
    // If we already have a debounce active but a new call to emit 
    // the state has come in, cancel the current one.
    if (this.debounceTimeout) {
        clearTimeout(this.debounceTimeout);
    }

    // Create a new timeout
    this.debounceTimeout = setTimeout(() => {
        this.http.post().subscribe();
    }, 500);
};

正如您在上面看到的,我正在从我的组件调用一个具有自定义“去抖动”功能的服务函数,以确保只有在上次调用后 500 毫秒内没有再次调用该函数时才会发生 API 请求。500ms内的任何调用都会取消之前设置的debounce函数发起API请求,并再次设置超时函数等待调用API请求。这可确保 API 仅被调用一次。

但是,如果我想将 API 请求的 observable 返回到我的组件控制器,我就会遇到如何从自定义去抖动/超时函数本身返回它的问题。目标是消除呼叫抖动,以便订阅者不仅只收到 1 个结果,而且之前的呼叫被取消(或根本不进行)。

4

1 回答 1

0

尝试利用debounceTime内置的Rxjs

import { debounceTime, switchMap } from 'rxjs';
...
emitNewState$ = new Subject();
...

ngOnInit() {
  this.listenToEmitNewState$();
}
....
emitNewState() {
  this.emitNewState$.next();
}

listenToEmitNewState$() {
  this.emitNewState$.pipe(
    debounceTime(500),
  ).subscribe(() => {
    // do what you want, but if you're going to do an HTTP call, use switchMap like how it is commented below
  });

  //this.emitNewState$.pipe(
    // debounceTime(500),
     //switchMap(() => this.http.post()),
  // ).subscribe(() => {....});
}

于 2020-03-31T22:03:51.830 回答