发送并行http get in switchmap-Angular

时间:2019-08-03 08:33:26

标签: angular rxjs

我正在尝试通过并行发送聚合/方面查询和实际搜索查询来优化关键字搜索引擎的性能。

我尝试了许多解决方案,尤其是其中一种:

Angular2: which is the best way to make multiple sync calls with Observables?

问题是此解决方案使用forkJoin并行发送呼叫,但等待所有http返回。这打败了我的并行通话点。我的理解是,解决方案是使用相同类型的代码,但改用mergeMap。

我现有的代码如下:

ngOnInit(): void {
    this.route.queryParamMap
      .pipe(
        // extract parameters
        switchMap(params => {
          const requestedQuery = params.get('query');
          if (this.query !== requestedQuery) {
            // we reset the results and criteria
            this.results = undefined;
            this.aggregationCriteria = [];
          }
          this.query = requestedQuery;
          // set the search field
          this.searchForm.get('search').setValue(this.query);
          // extract the page if present
          const page = this.extractPageFromParameters(params);
          // extract the aggregations if there are some
          // we consider all parameters as potential aggregations, except `query` and `page`
          this.aggregationCriteria = this.extractCriteriaFromParameters(params);
          // launch the search
          return this.searchService.search(this.query, true, this.aggregationCriteria, page)
          // handle a potential error, by returning no result
          // but allow to trigger a new search
            .pipe(
              catchError(() => EMPTY)
            );
        })
      )
      .subscribe(results => {
        this.loading = false;
        // sets the results and the aggregations if there are some
        this.results = results;
        if (results.aggregations.length) {
          this.aggregations = results.aggregations;
        }
      });
    this.suggesterTypeahead = this.searchService.getSuggesterTypeahead();
  }

在很多方面,我都尝试了以下方法,但是此最新版本无法编译,我陷入了困境。任何建议或提示都将受到欢迎。

ngOnInit(): void {
    this.route.queryParamMap
      .pipe(
        // extract parameters
        switchMap(params => {
          const requestedQuery = params.get('query');
          if (this.query !== requestedQuery) {
            // we reset the results and criteria
            this.results = undefined;
            this.aggregationCriteria = [];
          }
          this.query = requestedQuery;
          // set the search field
          this.searchForm.get('search').setValue(this.query);
          // extract the page if present
          const page = this.extractPageFromParameters(params);
          // extract the aggregations if there are some
          // we consider all parameters as potential aggregations, except `query` and `page`
          this.aggregationCriteria = this.extractCriteriaFromParameters(params);
          // launch the search and handle a potential error, by returning no result
          // but allow to trigger a new search
          // return this.searchService.search(this.query,  this.aggregationCriteria, page)
          //   .pipe(
          //     catchError(() => EMPTY),
          //   );
          return map(
            searchQuery => {
              return this.searchService.search(this.query,  this.aggregationCriteria, page)
                .pipe(
                  catchError(() => EMPTY),
                );
            },
              aggQuery => {return this.searchService.aggregate(this.query,  this.aggregationCriteria) // ERROR: "TS7006: Parameter 'aggQuery' implicitely has 'any' type "
              .pipe(
                catchError(() => EMPTY)
              );
            }
            );
        }))
      .subscribe(results => {
        this.loading = false;
        if (results.aggregations.length) {//ERROR: "TS2339: Property aggregation does not exist on type '{}'"
          // sets the aggregations if there are some
          this.aggregations = results.aggregations;
        } else {
          this.results = results;
        }
      });
    this.suggesterTypeahead = this.searchService.getSuggesterTypeahead();
  }

1 个答案:

答案 0 :(得分:1)

如果您希望所有请求并行执行并使它们在完成时发出,那么您真正想要的是合并在这里:

      return merge(
        this.searchService.search(this.query,  this.aggregationCriteria, page)
            .pipe(
              catchError(() => EMPTY),
            );
        },
        this.searchService.aggregate(this.query,  this.aggregationCriteria)
          .pipe(
            catchError(() => EMPTY)
          );
      );

缺点是在您的订阅处理程序中,除非您进行一些映射以帮助您弄清楚,否则您将真正不知道哪个是哪个。

地图不是可观察的,它是一个运算符,合并将获取两个可观察的对象并“合并”它们的结果。

顺便说一句,forkJoin并没有达到并行调用的目的,这只是一个不同的用例,在这种情况下,您想并行进行调用(即在开始另一个调用之前不要等待一个),但是要等到您可以采取所有行动结果,或者只是需要知道哪个结果属于哪个行动。