java - 通过 Flux.create / Flux.switchMap 的可变间隔
问题描述
我需要一个基于用户输入可变的计时器。这是最小的例子:
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
- 从默认的 1 秒间隔开始
上面的switchMap
部分在下面工作,即我看到它每秒记录“订阅:N”,但“创建”不会被记录,e.next(2)
也不会被调用。
为什么这不起作用?这个用例有更好的解决方案吗?
解决方案
如 JavaDoc 中所述,Flux#startWith
将预先设置给定的序列。
由于您作为参数传递Flux.interval(Duration.ofSeconds(1))
,它将每秒无限发出 long,并且您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
在此处使用。
推荐阅读
- html - 有没有办法将 html 元素绝对定位但仍将其放置在页面的中心?
- python - 如何减少列表遍历器的执行时间限制
- android - 在同一个按钮上使用 android:background@drawable 和 stateListAnimator 会导致问题
- java - 找不到类“android.view.menu”
- python-3.x - CSV 文件未使用 pandas 数据框完全或正确上传
- php - 可以使用 PHP 的 password_hash 在 SQL 中设置默认用户的密码吗?
- python - 在 Mayavi 中使用 quiver3d() 绘制 3D 矢量场
- rust - 即使在 `&mut T` 存在的情况下,我是否可以将生命周期参数强制为更短的生命周期(健全)?
- parsing - 方案/球拍:如何在定义语法时重复
- ios - Admob IOS swift GDPR 同意