Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJS:使用更多/更少的观察值来更新“combineLatest”_Javascript_Rxjs_Reactivex - Fatal编程技术网

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。我添加了我自己的答案,希望能澄清我在寻找什么。