无法使 debounceTime() 或 throttleTime() 处理 Angular http 请求

Can't make debounceTime() or throttleTime() to work on an Angular http request

为了我的生活,我无法完成这项工作。 我搜索了又搜索,但找不到任何示例(所有示例都在 http.get 上带有 .fromEvent()、none)。

在我的模板中,我有这样的输入:

<input type="text" (input)="categoriesSearch($event)">

在我的组件中,我有以下内容:

categoriesSearch(event) {
    this.categoriesSubscription = this.apiService
        .getCategoriesList(this.uploadForm.get('categories').value)
        .debounceTime(3000)
        // .throttleTime(3000)
        .subscribe(
            (response) => {
                this.categories = response.data;
            }
        );
}

这是我的 ApiService 中的方法:

getCategoriesList(keyword = null) {
    const headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append('Bearer', this.authService.user.token);

    const getParams: URLSearchParams = new URLSearchParams();
    getParams.set('keyword', keyword);
    return this.http.get(this.apiHost + '/categories', { headers: headers, search: getParams })
        .map(response => response.json());
}

categoriesSearch()方法中,debounceTime()throttleTime()我都试过了(我也导入了,当然是import 'rxjs/add/operator/debounceTime'import 'rxjs/add/operator/throttleTime') .

但是 http.get 请求根本没有被反跳或限制!如果我在 3 秒内键入 10 个字符,它会发出 10 个 http 请求。

如果自上次请求或自 'no request'(意味着最初的 3 秒延迟)起至少已过去 3 秒,我究竟如何告诉 this.http.get 才发出请求?好吧,也许在这里我应该说 "since I've last typed something in my input".

我也试过直接在服务中使用 debounceTime()/throttleTime(),在 .map() 运算符之前 - 但结果是一样的。

But the http.get request is not debounced or throttled at all! If I type 10 characters in 3 seconds, it makes 10 http requests.

您的实施方式有误。您需要先捕获输入,应用 denounce 并进行 HTTP 请求。

您可以通过多种方式实施

1) Observable.fromEvent

 <input type="text" #input>

组件

 @ViewChild('input') text: ElementRef;

  ngAfterViewInit() {
    let text$ = Observable.fromEvent(this.text.nativeElement, 'keyup')
     .do(() => console.log("keyup"))
    .debounceTime(3000)
     .distinctUntilChanged()
    .switchMap(() => getCategoriesList())
        .subscribe(res => console.log(res));
  }

2) 使用主题

<input type="text" (keyup)="search($event)">

组件

  searchTerms = new Subject<string>();

search(term: string): void {
    this.searchTerms.next(term);
  }

ngOnInit(): void {

    this.searchTerms
      .debounceTime(3000)
      .distinctUntilChanged()
      .switchMap(() => getCategoriesList())
      .subscribe(term => { 
       console.log();
     });

3) 使用表单控件

 <input type="text" [formControl]="term">

组件

  term = new FormControl();

  ngOnInit() {
    this.items = this.term.valueChanges
                 .debounceTime(3000)
                 .distinctUntilChanged()
                 .switchMap(term => getCategoriesList(term))
                 .subscribe(res => console.log(res));
  }

使用表单控件

 <input type="text" [formControl]="term">

组件

term = new FormControl();

  ngOnInit() {
    this.items = this.term.valueChanges
                 .debounceTime(3000)
                 .distinctUntilChanged()
                 .switchMap(term => getCategoriesList(term))
                 .subscribe(res => console.log(res));
  }

重要的是执行订单操作,将 debounceTime 移到 getCategoriesList() 上方并且它有效