首页 > 解决方案 > 如何构建一个基于先前结果调用多个可观察对象的可观察对象?

问题描述

我有一个返回的端点{ ids: [1, 2, 3, 45] }

另一个返回给定 id 的值:{ id: 3, value: 30, active: true }

我正在尝试构建一个调用第一个端点的可观察对象,并为每个返回的 id 调用第二个端点并发出所有active = true值的总和:

private getIds(group: string) {
  const url = '...';
  return this.http.get<{ ids: number[] }>(url, { params: { group } });
}

private getValue(id: number) {
  const url = '...';
  return this.http.get<ActiveValue>(url, { params: { id: id.toString() } });
}

public getSum(group: string) {
  let sum = 0;
  const bSubject = new BehaviorSubject(sum);

  const observables = this.getIds(group).pipe(
    mergeMap(({ ids }) => ids),
    map(id => this.getValue(id).pipe(tap(({ value, active }) => {
      if (active) {
        sum += value;
        bSubject.next(sum);
      }
    })))
  );

  const observable = forkJoin(observables).pipe(map(() => sum));
  return { bSubject, observable };
}

interface ActiveValue {
  value: number;
  active: boolean;
}

但它抱怨:

forkJoin is deprecated: Use the version that takes an array of Observables instead (deprecation)

另外,当我将鼠标悬停在observables它上面时,它会显示:

const observables: Observable<Observable<ActiveValue>>

...虽然我认为它应该是Observable<ActiveValue>[]

我怎样才能让它工作?

标签: angulartypescriptrxjsrxjs6

解决方案


我不舒尔,但你可以尝试这样的事情

interface ActiveValue {
    value: number;
    active: boolean;
}

function countActiveValues(values: ActiveVale[]) {
    return values.reduce((acc, { value, active }) => acc + active ? value : 0, 0)
}

class MyClass {
    private getIds(group: string) {
        const url = '...';
        return this.http.get < { ids: number[] } > (url, { params: { group } });
    }

    private getValue(id: number) {
        const url = '...';
        return this.http.get < ActiveValue > (url, { params: { id: id.toString() } });
    }

    private getRequests(ids: number[]) {
        return ids.map((id) => this.getValue(id));
    }

    public getSum(group: string) {
        return this.getIds(group).pipe(
            map(({ ids }) => this.getRequests(ids)),
            switchMap((requests) => forkJoin(requests)),
            map((results) => countActiveValues(result))
        );
    }
}

并且不要忘记为您的请求捕获错误;)


推荐阅读