【问题标题】:Cancel previous backend request if a new one is created如果创建了新的后端请求,则取消先前的后端请求
【发布时间】:2019-04-20 07:43:35
【问题描述】:

我需要创建一个 Angular 组件来允许用户选择带有类型建议的城市。

当用户输入三个或更多字符时,前端会向后端询问名称以用户输入开头的城市列表。

之后,我将城市列表的 Observable 传递给 mat-option 组件

searchCities = (value: string): Observable<City[]> => {
    if(value.length >= this.minCityNameLength){
      return this.detailsITService.fetchCitiesByName(value);
    }

    return of([]);
};

如果使用新的用户输入调用方法searchCities(作为输入参数传递给我的自定义组件),是否有办法“取消”请求?

【问题讨论】:

  • 我不认为你可以取消请求,但你可以使用 buffer() 和 filter 来组合和减少调用开销。您可以缓冲以保持网络调用直到某个时间点,并过滤以确保输入得到验证
  • @Talha 是的,Angular 中的 HttpClient 实际上可以取消请求。

标签: typescript rxjs observable angular6


【解决方案1】:

Typeahead 是一个很常见的问题,而 rxjs 是处理这个问题的绝妙工具。假设input$ 是一个可观察的发射用户输入的搜索字符串,你可以这样做:

input$.pipe(
  // This is optional, just a suggestion. It prevents a
  // request from being started while the user is still
  // quickly typing a word. The value is a time in ms, see
  // the operators docs for details.
  debounceTime(250),

  // Here's the actual piece of code: switchMap will
  // start a new inner subscription whenever a new search
  // input comes along, cancelling any still on-going previous
  // request. This avoids any race conditions.
  switchMap(input => input.length > this.minCityNameLength
    ? this.detailsITService.fetchCitiesByName(input)
    : of([])
  )
).subscribe(…);

例如,您设置input$ 流的方式是

<input type="text" (input)="input$.next($event.target.value)" />

input$ 定义为

public input$ = new Subject<string>();

您可以找到一个工作示例here。你也可以看到debounceTime在里面的效果,你打开控制台试试看有没有操作符。

【讨论】:

  • 这是在 rx 中广泛使用的解决方案,我有同样的案例使用 rxjava 实现它!我在上面的评论中错误地写了缓冲区而不是去抖动!
猜你喜欢
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 2012-08-19
  • 2020-10-26
  • 2018-12-12
  • 2017-05-16
  • 2019-07-19
  • 1970-01-01
相关资源
最近更新 更多