Angular9 防抖優(yōu)化

2020-07-06 15:36 更新

如果你需要發(fā)一個 HTTP 請求來響應(yīng)用戶的輸入,那么每次擊鍵就發(fā)送一個請求的效率顯然不高。最好等用戶停止輸入后再發(fā)送請求。這種技術(shù)叫做防抖??梢酝ㄟ^防抖來優(yōu)化與服務(wù)器的交互。

考慮下面這個模板,它讓用戶輸入一個搜索詞來按名字查找 npm 包。 當用戶在搜索框中輸入名字時,PackageSearchComponent 就會把這個根據(jù)名字搜索包的請求發(fā)給 npm web API

Path:"app/package-search/package-search.component.html (search)" 。

<input (keyup)="search($event.target.value)" id="name" placeholder="Search"/>


<ul>
  <li *ngFor="let package of packages$ | async">
    <b>{{package.name}} v.{{package.version}}</b> -
    <i>{{package.description}}</i>
  </li>
</ul>

這里,keyup 事件綁定會把每次擊鍵都發(fā)送給組件的 search() 方法。下面的代碼片段使用 RxJS 的操作符為這個輸入實現(xiàn)了防抖。

Path:"app/package-search/package-search.component.ts (excerpt)" 。

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))
  );
}


constructor(private searchService: PackageSearchService) { }

searchText$ 是來自用戶的搜索框值的序列。它被定義為 RxJS Subject 類型,這意味著它是一個多播 Observable,它還可以通過調(diào)用 next(value) 來自行發(fā)出值,就像在 search() 方法中一樣。

除了把每個 searchText 的值都直接轉(zhuǎn)發(fā)給 PackageSearchService 之外,ngOnInit() 中的代碼還通過下列三個操作符對這些搜索值進行管道處理,以便只有當它是一個新值并且用戶已經(jīng)停止輸入時,要搜索的值才會抵達該服務(wù)。

  • debounceTime(500) - 等待用戶停止輸入(本例中為 1/2 秒)。

  • distinctUntilChanged() - 等待搜索文本發(fā)生變化。

  • switchMap() - 將搜索請求發(fā)送到服務(wù)。

這些代碼把 packages$ 設(shè)置成了使用搜索結(jié)果組合出的 Observable 對象。 模板中使用 AsyncPipe 訂閱了 packages$,一旦搜索結(jié)果的值發(fā)回來了,就顯示這些搜索結(jié)果。

使用 switchMap() 操作符

switchMap() 操作符接受一個返回 Observable 的函數(shù)型參數(shù)。在這個例子中,PackageSearchService.search 像其它數(shù)據(jù)服務(wù)方法那樣返回一個 Observable。如果先前的搜索請求仍在進行中 (如網(wǎng)絡(luò)連接不良),它將取消該請求并發(fā)送新的請求。

請注意,switchMap() 會按照原始的請求順序返回這些服務(wù)的響應(yīng),而不用關(guān)心服務(wù)器實際上是以亂序返回的它們。

如果你覺得將來會復(fù)用這些防抖邏輯, 可以把它移到單獨的工具函數(shù)中,或者移到 PackageSearchService 中。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號