2

我目前面临一个问题,第一次搜索可能需要 5 秒,第二次搜索需要 2 秒,问题是,第一次搜索需要更长的时间,将“擦除”之后完成的请求的结果,因为通话结束后。

我试图阅读

切换地图

在 rxJs 中并尝试使用它,但从我的尝试来看,它不会取消订阅先前的请求并删除结果。

我在这里可能做错了什么,但我无法准确指出问题所在。

Merge 的结果有 3 个变化源(分页、排序或新的搜索条件),对 sendSearchCriteria 的调用返回使用的数据。

sendSearchCriteria 返回一个Observable

有什么让你想到的,我做错了吗?

感谢您的帮助,

private loadDogsResults = (filtersInformation: FilterSearchCriteria) => {
    merge(this.sort.sortChange, this.paginator.page, of(filtersInformation))
      .pipe(
        distinctUntilChanged(),
        tap(() => (this.isLoading = true)),
        switchMap(() => this.sendSearchCriteria(filtersInformation)),
        //mergeMap(() => this.sendSearchCriteria(filtersInformation)),
        map(data => this.formatResults(data)),
        finalize(() => (this.isLoading = false)),
        catchError(error => this.handleError(error)),
        takeUntil(this._onDestroy$)
      )
      .subscribe((result: any[]) => {
        if (result.length > 0) {
          this.setDisplayedColumns(result[0]);
        }
        this.isLoading = false;
      });
  }
4

3 回答 3

2

哪个事件触发search?此事件应该是您的 的来源Observable,它将与switchMap操作员一起“管道”。

正如我在这里看到的,如果您loadDogsResults()为每个事件调用,那么每次都创建一个新事件时它不会起作用Observable。是一个 Observable,它在订阅 observable 时of(filtersInformation)发出一次值,我认为这不是预期的行为。filtersInformation

于 2019-04-26T17:33:50.077 回答
1

您正在对 3 个单独的 observables 进行合并,这将导致您在 3 个不同的场合进入管道,并触发 3 个对 sendSearchCriteria 的单独调用。如果您要做的是调用 sortChange 和 page,获取两者的结果,然后调用 sendSearchCriteria,您可以...

private loadDogsResults = (filtersInformation: FilterSearchCriteria) => {
    forkJoin(this.sort.sortChange, this.paginator.page)
      .pipe(
        distinctUntilChanged(),
        tap(() => (this.isLoading = true)),
        switchMap(() => this.sendSearchCriteria(filtersInformation)),
        //mergeMap(() => this.sendSearchCriteria(filtersInformation)),
        map(data => this.formatResults(data)),
        finalize(() => (this.isLoading = false)),
        catchError(error => this.handleError(error)),
        takeUntil(this._onDestroy$)
      )
      .subscribe((result: any[]) => {
        if (result.length > 0) {
          this.setDisplayedColumns(result[0]);
        }
        this.isLoading = false;
      });
  }

但是请记住,在您的订阅中,您只能访问来自 sendSearchCriteria 的响应。

于 2019-04-26T17:34:17.250 回答
0

一位同事帮我找到了问题 :) 我们尝试了 forkJoin、combineLatest 和多个选项,但最大的问题是初始化/订阅以一种奇怪的方式完成。

我们现在创建了一个 searchTriggerSubject 并添加了这些行

  private initializeSubscription() {
    this.searchTriggerSubscription = this.searchTriggerSubject.pipe(
      tap(() => (this.isLoading = true)),
      switchMap(() => this.sendSearchCriteria(this.claimsFilters)),
      map(data => this.formatResults(data)),
      catchError(error => this.handleError(error)),
      takeUntil(this._onDestroy$)
    ).subscribe((result: any[]) => {
    if (result.length > 0) {
      this.setDisplayedColumns(result[0]);
    }
    this.isLoading = false;
  });
  }

  private initializeSearchTriggerValues() {
    this.sort.sortChange.subscribe(() => this.searchTriggerSubject.next())
    this.paginator.page.subscribe(() => this.searchTriggerSubject.next())
    this.filtersSubscription = this.claimsFiltersService.getFilterValues()
    .pipe(
      filter(filters => filters !== null),
      tap((filter) => this.claimsFilters = filter)
    )
    .subscribe(() => this.searchTriggerSubject.next());
  }

过滤器来自一项服务,所以这是我们为避免这个问题所做的。

需要进行一些重构

非常感谢大家提供不同的线索,拥有多个主题更容易

于 2019-04-29T07:48:15.090 回答