【问题标题】:Observable stream, whose values are enriched from other, "one-shot" Observables可观察流,其值从其他“一次性”可观察对象中丰富
【发布时间】:2019-02-26 15:06:28
【问题描述】:

我有一个辅助函数,它进行 API 调用并返回 items 数组。每一项都代表一个实体,比如User

每个用户都有一个category_id 属性,默认为空。我想从另一个辅助函数的结果中为每个用户填充此属性,该辅助函数接受用户 ID 并返回 Category 对象的 Observable,我可以从中提取 ID,用作 category_id 的属性用户。

我已经达到了以下(伪)代码(TypeScript 语法,但该问题通常适用于 Observable 运算符):

this.backend
    .request(
      'v1/users',
    )
    .pipe(
      map(items => {
        items.forEach(user => {
          this.categories.getName(user['id']).subscribe(category => {
            user['category_id'] = category['id'];
          });
        });
        return items;
      })
    )

这自然是行不通的,因为它将 Observable 运算符与数组函数 (forEach) 混合在一起。

【问题讨论】:

    标签: rxjs observable rxjs-pipeable-operators


    【解决方案1】:

    您不应该订阅管道中的 observable。这是一种反模式。 使用更高的 observable 和 mergeMap 和 combineLatest 来获得你想要的:

    this.backend
    .request(
      'v1/users',
    )
    .pipe(
      mergeMap(items => {
        const requestUserWithCatArray = items.map(user => this.categories.getName(user['id']).pipe(
            map(category => {
                 user['category_id'] = category['id'];
                 return user;
            })
        ));
        return combineLatest(requestUserWithCatArray);
      })
    );
    

    它将返回一组用户及其类别。

    【讨论】:

    • 您可以使用forkJoin 而不是combineLatest 来并行而不是按顺序运行请求(假设this.categories.getName(user['id']) 完成)。
    • forkJoin 在这种情况下可能会更好用,是的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 2021-12-28
    • 1970-01-01
    • 2019-07-07
    • 2019-12-31
    相关资源
    最近更新 更多