angular請求的防抖(debounce)

在開發項目過程中,我們會遇到這樣的場景:

當用戶在搜索框中輸入名字時,當用戶輸入完畢後,自動發送搜索請求,實時響應;而不是多按一個按鈕或者回車鍵。

如果按照常規思路,我們會綁定inputkeyup事件,每次擊鍵後,執行相對應的請求函數。

但是,如果每次擊鍵都發送一次請求,會造成請求過多,成本太昂貴了。 最好能等到用戶停止輸入時才發送請求

那麼,使用 RxJS 的操作符就能輕易實現它,參見下面的代碼片段(search.component.ts):

withRefresh = false;
packages$: Observable<NpmPackageInfo[]>;
private searchText$ = new Subject<string>();
 
search(packageName: string) {
  this.searchText$.next(packageName);
}
 
ngOnInit() {
  this.packages$ = this.searchText$.pipe(
    debounceTime(500),
    distinctUntilChanged(),
    switchMap(packageName =>
      this.searchService.search(packageName, this.withRefresh))
  );
}

The searchText$ is the sequence of search-box values coming from the user. It’s defined as an RxJS Subject, which means it is a multicasting Observable that can also produce values for itself by calling next(value), as happens in the search() method.

searchText$ 是一個序列,包含用戶輸入到搜索框中的所有值。 它定義成了 RxJS 的 Subject 對象,這表示它是一個多播 Observable,同時還可以自行調用 next(value) 來產生值。 search() 方法中就是這麼做的。

debounceTime(500) - wait for the user to stop typing (1/2 second in this case).
debounceTime(500) - 等待,直到用戶停止輸入(這個例子中是停止 1/2 秒)。

distinctUntilChanged() - wait until the search text changes.
distinctUntilChanged() - 等待,直到搜索內容發生了變化。

switchMap() - send the search request to the service.
switchMap() - 把搜索請求發送給服務。

這些代碼把 packages$ 設置成了使用搜索結果組合出的 Observable 對象。

這樣,只有當用戶停止了輸入且搜索值和以前不一樣的時候,搜索值纔會傳給服務。

如果,覺得將來會複用這些防抖邏輯, 可以把它移到單獨的工具函數中,或者移到 SearchService 中。

switchMap() 操作符有三個重要的特徵:

  1. It takes a function argument that returns an Observable. PackageSearchService.search returns an Observable, as other data service methods do.(它的參數是一個返回 Observable 的函數。PackageSearchService.search 會返回 Observable,其它數據服務也一樣。)
  2. If a previous search request is still in-flight (as when the connection is poor), it cancels that request and sends a new one.(如果以前的搜索結果仍然是在途狀態(這會出現在慢速網絡中),它會取消那個請求,併發起一次新的搜索。)
  3. It returns service responses in their original request order, even if the server returns them out of order.(它會按照原始的請求順序返回這些服務的響應,而不用關心服務器實際上是以亂序返回的它們。)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章