转换Observable <observable <{t1:t1,=“”t2:=“”t2} =“”>&gt;至Observable&lt; {t1:T1,t2:T2} []&gt;

时间:2017-06-09 15:12:25

标签: stream rxjs observable

我有两个Observable:obs1和obs2

  • obs1 属于Observable<T1[]>类型(从a中检索) this.service1.getT1Arr()功能)
  • obs2 的类型为Observable<T2> (从this.service2.getT2(t1: T1)函数中检索)

我想创建一个 obs3 ,其类型为:

Observable<{t1: T1, t2: T2}[]>

我目前的问题是我用来检索obs2的函数将T1类型的对象作为参数,所以我需要按照以下步骤操作:

  1. 从T1 []数组
  2. 中检索T1类型的每个对象
  3. 对于每个此对象检索它 对应的对象T2
  4. 构造由这两个对象组成的对象
  5. 目前我有以下代码:

    obs3 = this.service1.getT1Arr().flatMap((t1Arr: T1[]) => {
        return t1Arr.map((t1) => {
            return this.service2.getT2(t1).map((t2: T2) => {
                return {
                    t1: t1
                    t2: t2
                }
            }
        }
    }
    

    但是我收到了错误

    Observable<Observable<{t1: T1, t2: T2}>> is not assignable to 
    Observable<{t1: T1, t2: T2}[]>
    

    所以我的问题是:如何在整个过程中保持我的数组类型而不是在交换Observable时丢失它?

    我已经看过组合运算符,例如 concat() merge()以及转换运算符 switchMap()但问题我的原因是我没有两个并行流,而是从另一个流创建的一个流。

    非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

问题在于flatMap旨在展平一个级别的嵌套。你实际上有两个,因为你从选择器函数返回Array Observables。你需要一层额外的展平:

const obs3: Observable<{T1, T2}[]> = 
  this.service1.getT1Arr().flatMap((t1Arr: T1[]) => {
    // Lift the t1Array into an Observable<T1>
    return Observable.from(t1Array)
      // Flatten the results of calling service2
      .concatMap(
        // Returns Observable<T2>
        t1 => this.service2.getT2(t1),
        // Use the result selector to map to your desired structure
        (t1, t2) => ({t1, t2})
      )
      // Gather the results back up Observable<{T1, T2}[]>
      .toArray();
});

答案 1 :(得分:0)

您需要使用flatMap将列表项的流转换为单个项的流,然后对于每个项t1,执行另一个fltaMap调用以获取t2。然后使用map来组合它们。看看这是否适合你

this.service1.getT1Arr()
    .flatMap(t1Arr: T1[] => Observable.from(t1Arr))
    .flatMap((t1 : T1)=> this.service2.getT2(t1)
         .map((t2:T2)=> {t1: t1, t2: t2})
     );

如果您希望将结果放在单个数组而不是流中,可以在最后一个flatMap之后添加.toArray()