为什么我调用了 save() 数据库里却没有数据?Mono.just 和 Mono.fromSupplier 有什么不同?订阅两次会执行两次吗?cache() 和 share() 区别?错误去哪里了?这篇用 Reactor 3.8.7 逐个打印执行顺序。
构造 Mono.fromSupplier(...).map(...).doOnNext(...)
构造完成,到这里为止上面没有任何输出;现在 subscribe
(supplier 被执行)
(map 被执行)
(doOnNext 被执行:v!)
(subscriber 收到 v!)
对照 Mono.just(expensive("A")):参数在构造时就算了
(expensive(A) 被执行了)
Mono.just(...) 构造完成,尚未订阅
对照 Mono.fromSupplier(() -> expensive("B")):
构造完成,尚未订阅
(expensive(B) 被执行了)
对照 Mono.defer(() -> Mono.just(expensive("C"))):
构造完成,尚未订阅
(expensive(C) 被执行了)链上没人订阅就什么都不发生;Mono.just 的参数是 Java 先算的。
同一个 Mono 订阅 3 次:
(源被执行,第 1 次)
订阅者收到 1
(源被执行,第 2 次)
订阅者收到 2
(源被执行,第 3 次)
订阅者收到 3
cache() 之后订阅 3 次:
(源被执行,第 1 次)
订阅者收到 1
订阅者收到 1
订阅者收到 1
Flux 同一个源被两个订阅者各订阅一次:
(Flux 源被执行,第 1 次)
订阅者 1 收到 10
订阅者 1 收到 11
(Flux 源被执行,第 2 次)
订阅者 2 收到 20
订阅者 2 收到 21
share() + 两个订阅者几乎同时订阅:
(Flux 源被执行,第 1 次)
订阅者 1 收到 10
订阅者 2 收到 10
订阅者 1 收到 11
订阅者 2 收到 11每次订阅重新执行;cache() 与 share() 才共用结果。
调用 save("x1") 但不订阅也不返回:
DB = []
调用 save("x2").subscribe():
(save(x2) 真正写入)
DB = [x2]
在 map 里调用返回 Mono 的 audit(x),不订阅:
结果 p
改成 flatMap(x -> audit(x).thenReturn(x)):
(audit(p) 真正执行)
结果 p
doOnNext(x -> audit(x))(同样丢了返回值):
结果 p
doOnNext(x -> audit(x).subscribe())(手动订阅,线程/错误都脱离了主链):
(audit(p) 真正执行)
结果 p返回 Mono 的方法必须接到链上,否则没有副作用。
multicast 先发了 1、2,然后才订阅,再发 3:
订阅者收到 1
订阅者收到 2
订阅者收到 3
directBestEffort(没有订阅者时发送)先发 1、2,再订阅,再发 3:
订阅者收到 3
replay().all() 先发 1、2,再订阅,再发 3:
订阅者收到 1
订阅者收到 2
订阅者收到 3
Flux.interval 是冷的:订阅者 B 晚 150 ms 订阅,也从 0 开始:
A 收到 0
A 收到 1
B 收到 0
A 收到 2
B 收到 1
B 收到 2订阅时机决定收到什么;不同 Sink 的缓存策略不同。
构造 CompletableFuture.supplyAsync(...)(还没有任何订阅):
(future 的任务在 ForkJoinPool.commonPool-worker-1 上被执行)
Mono.fromFuture(cf) 构造完成但还没订阅 —— 上面的任务其实早已执行
Mono.fromFuture(Supplier)(惰性):
构造完成,尚未订阅
现在订阅:
(惰性的 future 任务被执行)
订阅 2 次 Mono.fromFuture(cf):
收到 cf
收到 cfFuture 本身是 eager 的,包成 Mono 也不会变惰性。
subscribe() 不会等待:
subscribe() 返回,用时 1 ms
(300 ms 的 delay 完成)
block() 会等待并抛出异常:
block() 返回,用时 305 ms
block() 抛出 IllegalStateException: boom
没有 error 回调的 subscribe():
subscribe() 正常返回
有 error 回调的 subscribe(onNext, onError):
onError 收到 boom3
-- 程序打在标准错误 / 标准输出上的非 RES 行(共 4 行),前 3 行:
[ERROR] (main) Operator called default onErrorDropped - reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: boom2
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: boom2
Caused by: java.lang.IllegalStateException: boom2subscribe() 不等待,block() 等待,没有 error 回调的错误只进日志。