首页 > 解决方案 > 从 Angular 方法返回一个 Observable,包括 pipe、switchMap、forkJoin

问题描述

我需要以下代码来返回Observable<ApiResponse>. 我不确定这是否可行或者我需要不同的方法?

private doRequestProducts() {

        const sequence$ = this.http.post<ApiResponse>(this.baseUrlOverview, {} { observe: 'response' }).pipe(
        switchMap(res => {
          if (res.status !== 200) {
            throw new Error('Value expected!');
          }
          const productResponse: productOverviewResponse = {... res.body.data};
          const responses: Observable<ApiResponse>[] = [];
          productResponse.Products.forEach((item, index) => {
            const response: Observable<ApiResponse> = this.http.post<ApiResponse>(this.baseUrlDetail, {
              productID: item.productId,
            });
            responses.push(response);
          });

          return forkJoin(responses).pipe(
              map(d => {
                const items: product[]  = [];
                d.forEach((api) => {
                  if (api.status === 'ok') {
                    const invResp: product = {... api.data};
                    items.push(invResp);
                  }
                });
              })
            );
          }
        ));
      }

标签: angulartypescriptrxjs

解决方案


您忘记了 doRequestProducts 函数的返回语句。除此之外,我认为该方法看起来非常好,但可以使用一些小的改进。但是,请使用 map 而不是 foreach+push 方法。

建议:

private doRequestProducts(): Observable<Data[]> {
    return this.http.post<ApiResponse>(this.baseUrlOverview, { observe: 'response' }).pipe(
        tap(res => {
            if (res.status !== 200) {
                throw new Error('Value expected!');
            }
        }),
        map(res => res.body.data.Products),
        switchMap(products => {
            const productResponses: Observable<ApiResponse>[] = products.map(product => this.http.post<ApiResponse>(this.baseUrlDetail, { productID: product.productId }));
            return forkJoin(productResponses);
        }),
        map((responses: ApiResponse[]) => responses.filter(response => response.status === 'ok').map(response => response.data)),
    );
}

附加信息:

  • 它不会返回一个Observable<ApiResponse>. 它将返回具有数据对象类型的数组的 Observable。我在示例中将此类型数据命名为。
  • 似乎你有一种通用的 API 响应,每次使用它时都会映射它。您可能需要考虑从 ApiResponse 创建一个映射器到您需要接收更多类型安全的任何类型

推荐阅读