我需要一个基于用户输入变量的计时器。这是最小的示例:
Flux.<Integer> create(e -> {
log.info("create"); // Never gets triggered
e.next(2); // Sample user input: change to 2 second interval
})
.switchMap(v -> Flux.interval(Duration.ofSeconds(v)))
.startWith(Flux.interval(Duration.ofSeconds(1)))
.subscribe(e -> log.info("subscribe: {}", e)); // This works
在上面:
Flux<Integer>
,它应根据用户输入发出东西(在上面它仅发出2),switchMap
以上内容在switchMap
部分下面起作用,即我看到它每秒记录一次“ subscribe:N”,但是“ create”没有被记录,并且e.next(2)
也从未被调用。 / p>
为什么这不起作用?此用例是否有更好的解决方案?
答案 0 :(得分:1)
如JavaDoc中所述,Flux#startWith
将添加给定序列。
自从您传递Flux.interval(Duration.ofSeconds(1))
作为参数以来,它将无限地每秒发出一长串,并且您基于Flux.create
的发布者将永远不会得到订阅。
但是,如果将其更改为:
.startWith(Mono.delay(Duration.ofSeconds(1)))
您也可以考虑将代码更改为:
Flux.<Integer> create(e -> {
log.info("create");
e.next(2);
})
.startWith(1)
.switchMap(v -> Flux.interval(Duration.ofSeconds(v)))
.subscribe(e -> log.info("subscribe: {}", e));
在这里,我们在startWith
块之后立即使用Flux.create
,并让switchMap
像对待其他任何信号一样处理它。
另外,请注意,switchMap(v -> Flux.interval(Duration.ofSeconds(v)))
的读法是:
“每N秒开始发射一次,其中N是最新发射的值”
如果只需要“延迟”一次,请考虑在此处也使用Mono.delay
。