首页 > 解决方案 > 使用 rjxs 而不是 setTimeout 函数订阅的更优雅的方式?

问题描述

我有一个update()方法,我用它在表中搜索某些条目并更新/过滤输入字段中每个击键的条目。

我的目标是在每次击键后等待大约 400 毫秒,然后再将请求发送到后端,这样我就可以避免太多无意义的请求。

目前我已经用这个setTimeout()函数实现了它,但我确信 RxJS 有一种更优雅的方式。

  update(searchInput: string) {
    setTimeout(() => {
      this.myService.search(searchInput)
      .subscribe((res) => {
        this.myArray.content = res;
      });
    }, 400);
  }

有人有什么想法吗?

标签: javascriptangulartypescriptrxjsrxjs6

解决方案


您正在寻找的是debounceTime。它在发射任何东西之前等待 x 毫秒。将它与其他运算符结合起来不会使您的 API 过载将是一个不错的选择。

你的 observable 看起来像

const search$ = fromEvent(search, 'input').pipe(
  debounceTime(400), // Wait 400 MS before outputting
  distinctUntilChanged(), // Only output unique values
  map(event => event.target.value), // Extract the value of the search
  switchMap((search) => service.doApi(search)) // SwitchMap to cancel a previous search if it wouldn't have completed
)
search$.subscribe()  // These might leak. Keep them in an array and clean them up when the component unloads

搜索元素将是组件的 viewChild。

import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
  @ViewChild('yourInput', {static: true}) search: ElementRef;

  searchSubscription: Subscription;

  ngOnInit(): void {
    const search$ = fromEvent(this.search.nativeElement, 'input').pipe(
      debounceTime(400), // Wait 400 MS before outputting
      distinctUntilChanged(), // Only output unique values
      map((event: KeyboardEvent) => (event.target as HTMLInputElement).value), // Extract the value of the search
      switchMap((search) => service.doApi(search)) // SwitchMap to cancel a previous search if it wouldn't have completed
    )  // Lives forever
    this.searchSubscription = search$.subscribe()
  }

  ngOnDestroy(): void {
    this.searchSubscription.unsubscribe()
  }
}



推荐阅读