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 要求が発生するようにしています。500 ミリ秒以内の呼び出しは、以前にセットアップされたデバウンス機能をキャンセルして API 要求を行い、API 要求を待機して呼び出すためのタイムアウト機能を再度セットアップします。これにより、API が 1 回だけ呼び出されるようになります。

しかし、API リクエストのオブザーバブルをコンポーネント コントローラーに戻したい場合、カスタム デバウンス/タイムアウト関数自体からそれを返す方法の問題に直面しています。目標は、サブスクライバーが 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 に答える