我有一个问题,为什么这不是写入控制台数字2,4,6?是什么解释?
max
答案 0 :(得分:2)
基本问题是,只有当前一个Observable完成时,才会使用concatMap
订阅下一个Observable。 groupBy
会发出两个GroupedObservable
,所以它订阅了第一个,我认为它可以订阅链完成的第二个。这意味着观察者会收到来自第一个complete
的{{1}}通知,因此您永远不会看到来自第二个GroupedObservable
的值(说实话我并非100%确定它真的发生了像这样,但没有进一步调查你的例子是有意义的。)
因此,如果您只想要第二组:
GroupedObservable
查看实时演示(开放式控制台):https://stackblitz.com/edit/rxjs5-sfused
我检查了源代码,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
订阅第二个Observable。
请参阅:https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/groupBy.ts#L200-L210
答案 1 :(得分:1)
问题是groupBy
运算符为每个键发出Subjects
。
Concat映射仅在第一个Subject
完成后才订阅后续的Subject
,即,由于所有子流同时发出值,因此错过了从后续subjectSelector
捕获项目的机会。
恭喜:https://blog.angularindepth.com/those-hidden-gotchas-within-rxjs-7d5c57406041
TL; DR:
GroupBy收到ReplaySubject
作为第四个参数。您可以使用它来强制使用Subject
而不是Observable.range(1, 6)
.groupBy(
n => n % 2 === 0,
null,
null,
() => new ReplaySubject() // <-- Here we go
)
.concatMap(obs => obs)
.subscribe((n) => console.log(n))
(默认)。
class MiglayoutExample extends JFrame {
static JFrame frame;
public static void main(String[] args) {
frame = new JFrame("frame");
JPanel bluePanel = new JPanel();
bluePanel.setLayout(new MigLayout());
bluePanel.setBackground(Color.BLUE);
JPanel redPanel = new JPanel();
redPanel.setBackground(Color.RED);
bluePanel.add(redPanel, "width 100%, height 100%");
frame.add(bluePanel);
frame.setSize(600, 600);
System.out.println("bluePanel.getHeight() = " + bluePanel.getHeight()); //Output 0
System.out.println("bluePanel.getWidth() = " + bluePanel.getWidth()); //Output 0
System.out.println("redPanel.getHeight() = " + redPanel.getHeight()); //Output 0
System.out.println("redPanel.getWidth() = " + redPanel.getWidth()); //Output 0
frame.show();
}
}