【发布时间】:2018-05-26 19:13:27
【问题描述】:
我在创建以下 observable 时遇到问题。
我希望它接收预定义的值数组
我想过滤不同的东西,并能够将它们作为单独的可观察对象使用。
然后当需要合并这些过滤后的 observables 时,我想保留原始的顺序
//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$) };
}
现在,当我想为它编写一个测试时,我的问题就出现了。我尝试了以下在错误的问题上起作用的方法(使用玩笑)
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(); },
);
也许我可以通过另一种方式对其进行测试?
【问题讨论】:
-
input$.map(n => n + 2)并且您应该更仔细地查看您所期望的输出。 -
如果您在每个 Observable 上的“工作”一次只考虑一个值,那么正如 @cartant 所建议的,这不应被视为“过滤、处理、然后合并”,而只是直接映射。在最一般的情况下,您的映射函数将使用 if-else 将值指向不同的行为。如果他们自己返回 Observables,您可以concatMap 保留您的订单。
-
实际上我已经将地图和合并部分分离到另一个函数(获取源并返回接收器),并且当输入异步时它工作正常,但是当我尝试测试它时,这里输入是事先指定的,它不保留顺序...
-
这个其他函数在做什么?如果它不是映射函数,那么您必须更具体地说明“保留顺序”的含义。
-
你不能说两个独立的流之间元素的相对时间,即使它们来自同一个流。你在这里看到了后果。不管怎样,您的测试总是会中断,因为它依赖于因拆分原始流而中断的时间保证,您的生产代码也是如此。
标签: javascript rxjs rxjs5 reactivex