【问题标题】:Merge operator only emits the results of the first observable in list合并运算符仅发出列表中第一个可观察对象的结果
【发布时间】:2020-03-11 12:29:36
【问题描述】:

我正在尝试使用合并运算符来组合四个不同的可观察对象,它们都发出相同的类型T。我想合并四个可观察对象,以便我有一个发出 T[] 的可观察对象,然后我可以映射结果列表。

但是我注意到,当订阅合并的 observable 时,只会发出列表中第一个 observable 的结果。为什么是这样?

我认为这可能与正在使用的地图有关,但如果合并的 observable 的结果作为单个流发出,这肯定不是问题吗?

this._signalRService.categoryGroupChangeSignal.pipe(
          takeUntil(this.destroyObservables),
          switchMap(changedCategoryGroupId => {
                      return this.getAllCategoryGroups$().pipe(
                          map(groups => [changedCategoryGroupId, groups])
                      );
              }
          )).subscribe(([changedCategoryGroupId, groups]: [string, CategoryGroup[]]) => {
          //do stuff with merged groups list 
      });

getAllCategoryGroups$ = (): Observable<CategoryGroup[]> => {

        return this.tenantListService.tenantList.pipe(switchMap( (tenantList: Tenant[]) => {
          return merge(
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[0].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[1].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[2].id)
            )
        }));
  };

【问题讨论】:

  • 你有机会显示你在哪里订阅它吗?或者创建一个堆栈闪电战?

标签: javascript rxjs


【解决方案1】:

merge 运算符不会输出包含所有可观察值的数组。如果您的任何源 observables 发出一个新值,它就会发出一个值。

你想达到的可以用combineLatest来完成:

return this.tenantListService.tenantList.pipe(switchMap( (tenantList: Tenant[]) => {
          return combineLatest(
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[0].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[1].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[2].id)
            )
        }));

这将输出一个包含源 observables 的最新值的数组。但它只有在所有源 observable 发出至少一个值时才会发出!

【讨论】:

    【解决方案2】:

    如果你想要一个发出 T[] 的 observable,我建议使用 combineLatest。 CombineLatest 将等到所有内容都发出一个值,然后发出一个包含所有值的数组,每次发出一个新值时,都会发出所有这些值的最新值。而 merge 一次发出一个,只有发出的 observable 才会给你一个值。

    请务必注意,combineLatest 不会发出任何值,直到您提供 EVERY 可观察的它,在您的情况下,3 个不同的,至少发出 1 个值。

    combineLatest 的语法是相同的,因此您只需将 combineLatest 添加到您的 rxjs 导入并在 getAllCategoryGroups$ 中将 merge 更改为 combineLatest。

    getAllCategoryGroups$ = (): Observable<CategoryGroup[]> => {
    
        return this.tenantListService.tenantList.pipe(switchMap( (tenantList: Tenant[]) => {
          return combineLatest(
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[0].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[1].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[2].id)
            )
        }));
    

    };

    然后当您订阅它时,您将收到一个长度与您的 combineLatest 中的 observable 数量相同的数组

    要展平数组数组,您可以使用map 运算符,它允许您更改传递到可观察链的输出。进入地图后,您可以通过多种方式展平数组,但我通常只是这样做:

    getAllCategoryGroups$ = (): Observable<CategoryGroup[]> => {
    
        return this.tenantListService.tenantList.pipe(switchMap( (tenantList: Tenant[]) => {
          return combineLatest(
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[0].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[1].id),
            this._categoryGroupService.getCustomTenantCategoryGroups(tenantList[2].id)
            ).pipe(
                 map(lists => {
                    const arrayToReturn = [];
                    for (const list of lists) {
                        arrayToReturn.push(...list);
                    }
    
                    return arrayToReturn;
                 })
            )
        }));
    

    };

    【讨论】:

    • 这更像是我想要的。现在,当我使用 combine latest 时,我得到一个包含三个列表的列表,内部列表包含我需要的详细信息。是否有一个运算符可以用来将列表展平为所有详细信息的单个列表?另外我的 IDE 说 combineLatest 已被弃用,我应该使用其他版本吗?
    • comineLatest 中的一个参数已被弃用,函数本身不是。它说要通过管道映射而不是使用该参数,这是我在更新中所做的,尽管我们一开始并没有使用该参数。但是请确保您使用来自 rxjs 的 combineLatest 而不是来自 rxjs/operators 的一个表单运算符已被弃用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-11
    • 2021-10-31
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多