内部地图没有在 Rxjs 中被调用

Posted

技术标签:

【中文标题】内部地图没有在 Rxjs 中被调用【英文标题】:Inner map not getting called in 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 不是可迭代的类。

我在这里误会了什么?

【问题讨论】:

【参考方案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 对不起,我不得不解释其中的区别。我更新了答案,希望对你有帮助!

以上是关于内部地图没有在 Rxjs 中被调用的主要内容,如果未能解决你的问题,请参考以下文章

如何在可观察的地图中抛出Error(rxjs6,ng6)

Angular 7 RxJs - HTTP 调用未在 ForkJoin 中完成

如何使用 RxJS 以时间间隔调用多个依赖 api 调用

resignFirstResponder 没有在 textFieldShouldClear 中被调用

完全没有在 Observable 订阅方法中被调用

iOS - CLLocation Manager didUpdateLocations 在一个类中被调用,而不是在另一个类中?