【问题标题】:Inner map not getting called in Rxjs内部地图没有在 Rxjs 中被调用
【发布时间】:2020-09-23 04:06:29
【问题描述】:

我有这段代码,它使用两个管道来加载产品实例及其播放列表。如果加载播放列表时出错,该属性设置为null:

getProduct(productId: number): Observable<ProductDTO> {
    return this.internalFindOne(productId).pipe(
      flatMap((productDTO: ProductDTO) => {
        return this.productPlaylistService.getProductPlaylist(productId).pipe(
          map((productPlaylistDTO: ProductPlaylistDTO) => {
            productDTO.playlist = productPlaylistDTO;
            return productDTO;
          }),
          catchError(() => {
            // If product playlist doesn't find anything, we still have to return the product dto object
            productDTO.playlist = null;
            return of(productDTO);
          }),
        );
      })
    );
}

它已经以这种方式工作了。但是,我认为flatMap 不适合这里。没有编译器错误,但据我所知flatMap 以 1:n 方式工作,而 map 以 1:1 fashion 工作。我的代码期望 productDTO 作为此处的输入并返回相同的 productDTO 修改。但是当我用map 替换flatMap 调用时,嵌套的map 函数停止被调用(无论是成功部分还是错误部分)。

ProductDTOProductPlaylistDTO 不是可迭代的类。

我在这里误会了什么?

【问题讨论】:

    标签: typescript rxjs nestjs


    【解决方案1】:

    flatMap 的 'flat' 前缀意味着它将返回的 observable 展平,因此您将获得返回的 observable 数据而不是 observable 本身。这就像删除一个 level 嵌套的 observables。它的工作原理与switchMap 非常相似。您可以阅读 here 的区别。

    同时map只是转换数据,所以如果你从map()返回一个observable,你会得到这个observable的结果:

    internalFindOne(productId).pipe(
      flatMap(() => {
        return getProductPlaylist(productId);
      }),
      tap((additionalData: ProductPlaylistDTO) => { ... })
    );
    
    internalFindOne(productId).pipe(
      map(() => {
        return getProductPlaylist(productId);
      }),
      tap((additionalData$: Observable<ProductPlaylistDTO>) => { ... })
    );
    

    但在您的情况下,由于这两个请求不相互依赖,您可以使用combineLatest 同时执行它们:

    getProduct(productId: number): Observable<ProductDTO> {
      return combineLatest([
        this.internalFindOne(productId),
        this.productPlaylistService.productPlaylistService(productId).pipe(
          catchError(() => {
            return of(null);
          })
        ),
      ]).pipe(
        map(([ product, playlist ]) => {
          product.playlist = playlist;
          return product;
        })
      );
    }
    

    StackBlitz

    【讨论】:

    • 很好的重写!它有效.. 但是我想知道在我的情况下flatMap 发生了什么:-(
    • @XtremeBiker 对不起,我不得不解释其中的区别。我更新了答案,希望对你有帮助!
    猜你喜欢
    • 1970-01-01
    • 2022-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多