为什么concatMap没有订阅所有groupBy Observable rxjs?

为什么concatMap没有订阅所有groupBy Observable rxjs?,rxjs,rxjs5,Rxjs,Rxjs5,我有一个问题,为什么写这封信不是为了安慰数字2,4,6?原因是什么 Observable.range(1, 6) .groupBy(n => n % 2 === 0) .concatMap(obs => obs) .subscribe((n) => console.log(n), null, () => console.log('complete concatMap')) // this is the output 1 - 3 - 5 - complete

我有一个问题,为什么写这封信不是为了安慰数字2,4,6?原因是什么

Observable.range(1, 6)
  .groupBy(n => n % 2 === 0)
  .concatMap(obs => obs)
  .subscribe((n) => console.log(n), null, () => console.log('complete concatMap'))

// this is the output
1 -
3 -
5 -
complete concatMap

基本问题是,您使用的是
concatMap
,它只在前一个观测完成时订阅下一个可观测值
groupBy
发出两个
GroupedObservable
s,因此它订阅了第一个,我想在它订阅第二个之前,链就完成了。这意味着观察者从第一个
GroupedObservable
接收到
complete
通知,因此您永远看不到第二个
GroupedObservable
的值(老实说,我不是100%确定是否真的发生了这种情况,但在不进一步调查您的示例的情况下,这样做是有意义的)

因此,如果您只想要第二组,您可以:

import { Observable } from 'rxjs';

Observable.range(1, 6)
  .groupBy(n => n % 2 === 0)
  .filter(o => o.key === true)
  .concatMap(obs => obs)
  .subscribe((n) => console.log(n), null, () => console.log('complete concatMap'))
请参阅实时演示(打开控制台):

我检查了源代码,
groupBy
在收到
complete
通知后完成了所有的组(在收到
range
中的所有值后会这样做),因此没有空间让
concatMap
订阅第二个可观察值


请参见:

问题在于,
groupBy
操作员为每个键发出
主题

Concat map仅在第一个主题完成后才订阅后续主题,即它错过了从后续主题捕获项目的机会,因为所有子流同时发出值

荣誉:

TL;医生:

接收
subjectSelector
作为第四个参数。您可以使用它强制使用
ReplaySubject
而不是
Subject
(默认)

可观测范围(1,6)
.群比(
n=>n%2===0,
无效的
无效的
()=>新建ReplaySubject()//obs)
.subscribe((n)=>console.log(n))

感谢您的回答,我本以为concatMap会将第二个可观察到的(偶数)放入队列,并在第一个可观察到的(奇数)完成后订阅,但我猜我错了。你会怎么做才能得到这样的
1-3-5-2-4-6
,因为使用mergeMap我得到了
1-2-3-4-5-6
,而使用switchMap得到了这样的1-2-4-6,我同意这有点出乎意料,但如果你看看源代码,这就是它真正的功能。我在想怎么做,但如果不把链条一分为二,使用一个我觉得有点蹩脚的中间主题,我想不出任何聪明的解决方案。如果您不需要使用
groupBy
,我想您也可以使用
scan
进行同样的操作。
Observable.range(1, 6)
  .groupBy(
    n => n % 2 === 0,
    null, 
    null,
    () => new ReplaySubject() // <-- Here we go
  )
  .concatMap(obs => obs)
  .subscribe((n) => console.log(n))