【问题标题】:How to concat two observable arrays into a single array?如何将两个可观察数组连接成一个数组?
【发布时间】:2017-05-23 17:38:19
【问题描述】:

示例:

var s1 = Observable.of([1, 2, 3]);

var s2 = Observable.of([4, 5, 6]);

s1.merge(s2).subscribe(val => {
   console.log(val);
})

我想得到 [1,2,3,4,5,6]

而不是

[1,2,3]

[4,5,6]

【问题讨论】:

  • 如果我这样做了Observable.forkJoin(s1, s2),我会得到 [[1,2,3], [4,5,6]]

标签: rxjs observable


【解决方案1】:

forkJoin 效果很好,你只需要展平数组:

const { Observable } = Rx;

const s1$ = Observable.of([1, 2, 3]);
const s2$ = Observable.of([4, 5, 6]);

Observable
  .forkJoin(s1$, s2$)
  .map(([s1, s2]) => [...s1, ...s2])
  .do(console.log)
  .subscribe();

输出:[1, 2, 3, 4, 5, 6]

Plunkr 演示:https://plnkr.co/edit/zah5XgErUmFAlMZZEu0k?p=preview

【讨论】:

    【解决方案2】:

    使用Observable.from 代替Observable.of,它将一个数组作为参数并重新发送其所有值:

    var s1 = Observable.from([1, 2, 3]);
    var s2 = Observable.from([4, 5, 6]);
    
    s1.merge(s2).subscribe(val => {
       console.log(val);
    });
    

    也许你可能更喜欢concat 而不是merge,但在这种情况下使用普通数组它会给出相同的结果。

    这会给你:

    1
    2
    3
    4
    5
    6
    

    如果您希望将其作为单个数组,您还可以附加 toArray() 运算符。顺便说一句,你可以用Observable.of 来实现同样的效果,但你必须用Observable.of.call(...) 来调用它,这可能是不必要的复杂,而且使用Observable.from() 更容易。

    【讨论】:

    • 如果你有一个可观察数组怎么办?即 (s1, s2, ..., sN)
    【解决方案3】:

    我的看法是 zip 并与 Array.prototype.concat() 映射:

    https://stackblitz.com/edit/rxjs-pkt9wv?embed=1&file=index.ts

    import { zip, of } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    const s1$ = of([1, 2, 3]);
    const s2$ = of([4, 5, 6]);
    const s3$ = of([7, 8, 9]);
    ...
    
    zip(s1$, s2$, s3$, ...)
      .pipe(
        map(res => [].concat(...res)),
        map(res => res.sort())
      )
      .subscribe(res => console.log(res));
    
    

    【讨论】:

      【解决方案4】:

      也许你可以用 List 而不是 Array 来做到这一点:

      var s1 = Rx.Observable.of(1, 2, 3); 
      var s2 = Rx.Observable.of(4, 5, 6); 
      

      然后

      Rx.Observable.merge(s1,s2).toArray().map(arr=>arr.sort()).su‌​scribe(x=>console.l‌​og(x))
      

      【讨论】:

      • 我的来源是数组,所以这不是我的选择
      【解决方案5】:

      @maxime1992 接受的答案现在会导致当前版本的 RXJS 出现弃用警告。这是一个更新的版本:

      import { forkJoin, of } from 'rxjs';
      import { map } from 'rxjs/operators';
      
      const s1$ = of([1, 2, 3]);
      const s2$ = of([4, 5, 6]);
      
      Observable
        .forkJoin([s1$, s2$])
        .pipe(     
          .map(([s1, s2]) => [...s1, ...s2])
        )
      .do(console.log)
      .subscribe();
      

      【讨论】:

        猜你喜欢
        • 2018-05-19
        • 2019-02-25
        • 1970-01-01
        • 2016-05-14
        • 2021-09-20
        • 2018-06-20
        • 1970-01-01
        • 2021-10-22
        • 2017-05-06
        相关资源
        最近更新 更多