Javascript RxJS:使用更多/更少的观察值来更新“combineLatest”
我正在尝试做如下事情:Javascript RxJS:使用更多/更少的观察值来更新“combineLatest”,javascript,rxjs,reactivex,Javascript,Rxjs,Reactivex,我正在尝试做如下事情: const streams = []; streams.push(rxjs.fromEvent(uiItem1, 'input')); streams.push(rxjs.fromEvent(uiItem2, 'input')); streams.push(rxjs.fromEvent(uiItem3, 'input')); const combinedStream = rxjs.combineLatest(...streams); // In a galaxy far
const streams = [];
streams.push(rxjs.fromEvent(uiItem1, 'input'));
streams.push(rxjs.fromEvent(uiItem2, 'input'));
streams.push(rxjs.fromEvent(uiItem3, 'input'));
const combinedStream = rxjs.combineLatest(...streams);
// In a galaxy far, far away...
combinedStream.subscribe((bunchAValues) => {
const minValue = Math.min(bunchAValues);
// do cool stuff with minValue.
});
// Later, back on Earth:
streams.push(rxjs.fromEvent(uiItem4, 'input'));
delete streams[2];
// how to update combinedStream?
最后,我想做与之等价的combinedStream=rxjs.combinelatetest(…streams)代码>,但已就位。当然,我可以在不合适的地方这样做(这是一个术语吗?),但是我需要取消订阅旧的Observable并订阅新的Observable。我可以有一些额外的结构,通知遥远星系中的订阅者更新其对新观测的订阅,但是订阅者生活在程序的一个完全不同的部分,通过分离关注点,不必关心如何从combinedStream
添加和删除输入
我知道在适当的位置修改对象的想法违背了功能主义的哲学,我想RxJS会尽可能遵循这一哲学。同时,在我看来,我上面所要求的似乎是一件非常自然的事情:Andromeda中的订户只希望阵列流取最小值,而不管它们来自何处或组合了多少流
实现我想要的最简单、最优雅、最稳健的方式是什么
编辑:回想起来,我的问题本来可以说得更清楚。我在下面添加了我自己的答案,这基本上解决了问题,但并非没有陷阱。希望它能澄清我想要实现的目标。欢迎使用更好的解决方案。您可以使用takeUntil
和skipUntil
操作符:
从'rxjs'导入{fromEvent,CombineTest};
从'rxjs/operators'导入{takeUntil,skipUntil,first}
当ISEMITSEVERYTHINGCHANGES$=fromEvent时的常数(我的按钮“单击”)
.pipe(first());//假设您的事件是一个单击按钮。
const input1$=fromEvent(uiInput1,'input');
const input2$=fromEvent(uiInput2,'input')
.管道(直到(当发生任何变化时$);
const input3$=fromEvent(uiInput3,'input');
const input4$=fromEvent(uiInput4,'input')
.pipe(skipUntil(当发生严重变化时为$);
const combinedStream=combineTest([input1$、input2$、input3$、input4$);
//在一个遥远的星系里。。。
combinedStream.subscribe((bunchAValues)=>{
const minValue=Math.min(bunchAValues);
//用minValue做一些很酷的事情。
});
以下是我提出的解决方案:
class VariableSourceSubject extends rxjs.Subject {
constructor(joinFunction) {
super();
this.joinFunction = joinFunction;
this.sources = new Set();
}
addSource(source) {
this.sources.add(source);
this.renewInnerSubscription();
}
removeSource(source) {
this.sources.delete(source);
this.renewInnerSubscription();
}
hasSource(source) {
return this.sources.has(source);
}
renewInnerSubscription() {
const innerObservable = this.joinFunction(...this.sources);
if (this.innerSubscription) {
this.innerSubscription.unsubscribe();
}
this.innerSubscription = innerObservable.subscribe(this);
}
}
有了它,我可以做像这样的事情
const stream1 = streams.push(rxjs.fromEvent(uiItem1, 'input'));
const stream2 = streams.push(rxjs.fromEvent(uiItem2, 'input'));
const combinedStream = new VariableSourceSubject(rxjs.combineLatest);
combinedStream.addSource(stream1);
combinedStream.addSource(stream2);
// In a galaxy far, far away...
combinedStream.subscribe((bunchAValues) => {
const minValue = Math.min(bunchAValues);
// do cool stuff with minValue.
});
// Later, back on Earth:
const stream3 = rxjs.fromEvent(uiItem4, 'input'));
combinedStream.addSource(stream3);
combinedStream.removeSource(stream2);
// The subscription to combinedStream is now receiving the latest
// values from stream1 and stream3.
这对于我的用例来说似乎已经足够了,但并没有真正完全实现我最初的要求。具体来说,由于我正在将各种源与combineLatest
组合,并且每次添加或删除源时都会创建一个新的innerObservable
,因此在combinedStream
发出任何东西之前,所有剩余的源必须在每次删除/添加后至少发出一次。欢迎提供更好的解决方案。我认为您应该简化您的想法……感谢您的回答,很抱歉花了这么长时间才回到他的问题上。我发现我的问题有点不清楚:虽然你的解决方案适用于我给出的示例案例,但我真正想要的是能够让我不断添加和删除combinedStream
的输入内容,然而,您的解决方案似乎特别适用于添加一个输入,删除另一个输入,并称之为day。我添加了我自己的答案,希望能澄清我在寻找什么。