Mono.defer() 是做什么的?

2022-08-31 16:15:37

我在一些Spring webflux代码中遇到了Mono.defer()

我在文档中查找了该方法,但不明白解释:

“创建一个 Mono 提供商,该提供商将为每个下游用户提供要订阅的目标 Mono”

请我能有一个解释和一个例子。有没有一个地方有一堆反应堆示例代码(他们的单元测试?)我可以参考。

谢谢


答案 1

这有点过于简单化了,但从概念上讲,Reactor源要么懒惰,要么急于求成。更高级的,如HTTP请求,预计将被懒惰地评估。另一方面,最简单的人喜欢或渴望。Mono.justFlux.fromIterable

我的意思是,调用将立即调用该方法并捕获结果。所述结果仅在订阅后由发出。多次订阅也不会更改该值:Mono.just(System.currentTimeMillis())currentTimeMillis()Mono

Mono<Long> clock = Mono.just(System.currentTimeMillis());
//time == t0

Thread.sleep(10_000);
//time == t10
clock.block(); //we use block for demonstration purposes, returns t0

Thread.sleep(7_000);
//time == t17
clock.block(); //we re-subscribe to clock, still returns t0

该运算符是为了使此源变得懒惰,每次有新订阅者时重新计算 lambda 的内容:defer

Mono<Long> clock = Mono.defer(() -> Mono.just(System.currentTimeMillis()));
//time == t0

Thread.sleep(10_000);
//time == t10
clock.block(); //invoked currentTimeMillis() here and returns t10

Thread.sleep(7_000);
//time == t17
clock.block(); //invoke currentTimeMillis() once again here and returns t17

答案 2

当你运行Mono.just()时,它会立即创建一个Observable(Mono)并重用它,但是当你使用defer时,它不会立即创建一个新的Observable。

一个用例即可看出差异

    int a = 5;
@Override
public void run(String... args) throws Exception {

    Mono<Integer> monoJust = Mono.just(a);
    Mono<Integer> monoDefer = Mono.defer(() -> Mono.just(a));

    monoJust.subscribe(integer1 -> System.out.println(integer1));
    monoDefer.subscribe(integer1 -> System.out.println(integer1));

    a = 7;
    monoJust.subscribe(integer1 -> System.out.println(integer1));
    monoDefer.subscribe(integer1 -> System.out.println(integer1));
}

打印:

5
5
5
7

如果你看到 mono.just 立即创建了可观察量,即使值已更改,它也不会改变,但延迟会在订阅中创建可观察量,因此您将使用当前的 onSubscribe 值


推荐