ReactiveX过滤多次可观察并合并

时间:2017-12-13 00:40:58

标签: javascript rxjs rxjs5 reactivex

创建以下observable时遇到问题 我希望它接收预定义的数组值 我希望通过不同的东西进行过滤,并能够将它们作为单独的可观察对象进行处理 然后,当合并这些过滤的可观察量时,我想保留原始的

的顺序
//Not sure the share is necessary, just thought it would tie it all together
const input$ = Observable.from([0,1,0,1]).share();
const ones$ = input$.filter(n => n == 1);
const zeroes$ = input$.filter(n => n == 0);

const zeroesChanged$ = zeroes$.mapTo(2);
const onesChanged$ = ones$.mapTo(3);
const allValues$ = Observable.merge(onesChanged$,zeroesChanged$);

 allValues$.subscribe(n => console.log(n));
//Outputs 3,3,2,2
//Expected output 3,2,3,2
编辑:对不起,我的问题不够具体。 我正在使用一个名为cycleJS的库,它将副作用分成驱动程序。 所以我在我的周期中所做的就是这个

export function socketCycle({ SOCKETIO }) {
  const serverConnect$ = SOCKETIO.get('connect').map(serverDidConnect);
  const serverDisconnect$ = SOCKETIO.get('disconnect').map(serverDidDisconnect);
  const serverFailedToConnect$ = SOCKETIO.get('connect_failed').map(serverFailedToConnect);
  return { ACTION: Observable.merge(serverConnect$, serverDisconnect$, serverFailedToConnect$) };
}

现在我的问题出现了,当我想为它编写测试时。我尝试了以下哪些工作错误(使用jest)

const inputConnect$ = Observable.from(['connect', 'disconnect', 'connect', 'disconnect']).share();
const expectedOutput$ = Observable.from([
  serverDidConnect(),
  serverDidDisconnect(),
  serverDidConnect(),
  serverDidDisconnect(),
]);
const socketIOMock = {
  get: (evt) => {
    if (evt === 'connect') {
      return inputConnect$.filter(s => s === 'connect');
    } else if (evt === 'disconnect') {
      return inputConnect$.filter(s => s === 'disconnect');
    }
    return Observable.empty();
  },
};
const { ACTION } = socketCycle({ SOCKETIO: socketIOMock });
Observable.zip(ACTION, expectedOutput$).subscribe(
  ([output, expectedOutput]) => { expect(output).toEqual(expectedOutput); },
  (error) => { expect(true).toBe(false) },
  () => { done(); },
);

也许还有另一种方法可以测试它?

2 个答案:

答案 0 :(得分:1)

当对流进行分区时,实际上会破坏不同子流中的元素之间的时序保证。特别是,即使connect事件始终位于事件源的disconnect事件之前,connect Observable的事件也不会始终位于{{1}中的相应事件项之前可观察的。在正常的时间尺度下,这种竞争条件可能非常罕见但仍然很危险,而且这个测试显示了最坏的情况。

好消息是,您显示的功能只是事件和处理程序结果之间的映射器。如果您可以在事件类型上继续使用此模型,那么您甚至可以在纯数据结构中对映射进行编码,这有利于表达性:

disconnect

警告:如果你减少了子流(或以其他方式考虑以前的值,比如const event_handlers = new Map({ 'connect': serverDidConnect, 'disconnect': serverDidDisconnect, 'connect_failed': serverFailedToConnect }); const ACTION = input$.map(event_handlers.get.bind(event_handlers)); ),那么重构就不那么简单了,也依赖于新的“保留令”的定义。很多时候,使用debounceTime +复制更复杂的累加器仍然是可行的。

答案 1 :(得分:0)

下面的代码可能会给你想要的结果,但是没有必要使用rxjs来操作数组恕我直言

Rx.Observable.combineLatest(
   Rx.Observable.from([0,0,0]),
   Rx.Observable.from([1,1,1])
).flatMap(value=>Rx.Observable.from(value))
.subscribe(console.log)