无法从连接的Observable

时间:2017-01-07 22:51:49

标签: node.js rxjs5 angular2-observables

我有这个链,它应该将10个Observable连接成1个Observable,其中10个Observable中的每一个基本上都应该被解包为一个整数:

const Rx = require('rxjs');

var i = 0;
const obs = Rx.Observable.interval(10)
  .map(() => i++)
  .map(val => Rx.Observable.create(obs => {
          obs.next(val)
  }))
  .take(10)
  .reduce((prev, curr) => {
      return prev.concat(curr);  // concat all observables
  })
  .last(val => val.flatMap(inner => inner));

// subscribe to Observable
obs.subscribe(v => {
  console.log('\n next (and only) result => \n', v);
});

发生的事情是所有10个Observable都应该连接在一起,但我无法从这10个Observable中提取值(已成为1 Observable)。所以我的问题是,如何解开最终的observable并提取值?

任何人都知道我在说什么?

3 个答案:

答案 0 :(得分:1)

而不是reduce + last,您可以使用concatAll(或concatMap)来连接内部序列并保留顺序:

Observable
  .interval(0)
  .map(i => Observable.of(i))
  .take(10)
  .concatAll()
  .takeLast(1)
  .subscribe(v => console.log('\n next (and only) result => \n', v);)

修改:takeLast(1)代替finalValue()

答案 1 :(得分:1)

此问题与Observable.prototype.concatAll does not seem to yield expected result

中存在确切问题
.map(function(val){  // note: map *not* flatMap
  return Rx.Observable.create(obs => {
      obs.next(val)
  });
})

使用Rx.Observable.create创建自己的observable时,您需要自己.complete()。因为你忘记了这样做,.reduce()之类的运算符将无法工作,因为他们需要等待完成才能运行。

此外,您对.last()运算符的使用不正确;它需要一个谓词,您的流将被过滤,并且将发出与谓词匹配的最后一个发射。它也有点多余,因为.reduce()只会发出一个值。清理它会导致:

const obs = Rx.Observable.interval(10)
  .map(() => i++)
  .map(val => Rx.Observable.of(val))
  .take(10)
  .reduce((acc, curr) => acc.concat(curr))
  .flatMap(v => v)
  .toArray()

但你可以直接使用.concatMap()运算符而不是map + take + reduce + flatMap来缩短它:

const obs = Rx.Observable.interval(10)
  .map(() => i++)
  .concatMap(val => Rx.Observable.of(val))
  .take(10)
  .toArray()

答案 2 :(得分:0)

只需使用非原型方法。它不那么令人困惑。

let range = [...Array(10).keys()];

//array of 10 observables of 10 values each
let ten = range.map(i => Rx.Observable.interval(1000).map(_ => i).take(10));     
let sequence = Rx.Observable.concat(ten) // all of them in sequence