Javascript可观察对象:需要switchMap的功能,但略有不同

Javascript可观察对象:需要switchMap的功能,但略有不同,javascript,rxjs,observable,Javascript,Rxjs,Observable,我有一个Rxjs observable(stream,在下面的代码中),它发出observable(subsone和subtwo)。每一个内部可观测物都可以在任何时间以任何顺序发出它们自己的值。我的任务是从Subswone捕获值,直到Subswone发出第一个值 const subjOne = new Subject(); const subjTwo = new Subject(); const stream = Observable.create(observer => { o

我有一个Rxjs observable(
stream
,在下面的代码中),它发出observable(
subsone
subtwo
)。每一个内部可观测物都可以在任何时间以任何顺序发出它们自己的值。我的任务是从Subswone捕获值,直到Subswone发出第一个值

const subjOne = new Subject();
const subjTwo = new Subject();

const stream = Observable.create(observer => {
    observer.next(subjOne);
    observer.next(subjTwo);
});

stream
    .someOperator(subj => subj)
    .subscribe(value => console.log('Value: ', value));
例1:
subsone
发出值1和2,然后
subtwo
发出值3,然后
subsone
发出值4。 输出应为:1、2、3

例2:
subchone
发出1,然后
subchone
发出2。 输出应该是1

switchMap不适合这里,因为它会在
流发出
subchone
后立即从
subchone
中删除值。关于如何实现这一点有什么想法吗?谢谢


更新:在我的实际案例中,不仅有两个内部观察对象--
subchone
subchone
,而且它们是一个恒定的流,因此手动硬编码
subchone。takeUntil(subchone)
不是一个可行的选择。

听起来像是你在寻找的

takeUntil
侦听一个流,直到第二个流发出。所以请举个例子

// Emits every second
const source = Observable.timer(0, 1000);

// Emits once after 3 seconds
const canceller = Observable.timer(3000);

source
  // Takes from the source until this stream emits
  .takeUntil(canceller)
  .subscribe({
    next: x => console.log(`Value ${x}`),
    complete: () => console.log('Done')
  });
// Value 0 -> 0 seconds
// Value 1 -> 1 seconds
// Value 2 -> 2 seconds
// Done -> 3 seconds

你可以把你的两个主题拿出来,然后把它们与
结合起来,直到

const subjOne = new Subject();
const subjTwo = new Subject();

const stream = Observable.create(observer => {
    observer.next(subjOne);
    observer.next(subjTwo);
});

const first$ = stream.take(1).flatMap(x=>x)
const second$ = stream.skip(1).take(1).flatMap(x=>x)

first$.takeUntil(second$).subscribe(...)

我想这正是你想要的:

// scan to let us keep combining the previous observable
// with the next observable
source
  .scan((current, next) => {
    // takeUntil to stop current when next produces
    const currentUntil = current.takeUntil(next);
    // now merge current with next
    return currentUntil.merge(next)
  }, Rx.Observable.empty())
  // switch to the most recent version of the combined inner observables
  .switch();

注意,只有当内部可观测物是热的时,这种方法才能正常工作。如果它们是冷观测值,则需要更多的代码来实现。

是的,但是如果有100个观测值而不是只有两个呢?我的错,在我的例子中,我没有提到实际上有比两个多得多的内部观测值。那么,如何确定哪个流依赖于哪个流呢?它应该从任何内部观测值中吐出值,直到最近的一些内部观测值(称为X)发出它的第一个值。在这一点上,它应该忽略旧观测值的所有未来值,只使用观测值X的值。与原始问题中描述的相同,但有1000个观测值,而不是两个。所以,如果我正确理解了你的问题,那么重要的是这些内在观察物的出现顺序。