Mono/Flux.fromCallable 和 Mono.defer 之间的区别

Difference between Mono/Flux.fromCallable and Mono.defer

我通常有生成一个 Mono/Flux 的要求,其值在订阅时将是 generated/calculated。为此,fromCallable 和 defer 运算符似乎都很好。

我无法在 javadoc 中清楚地看出区别:

FromCallable:

public static Mono fromCallable(Callable supplier)

Create a Mono producing its value using the provided Callable. If the Callable resolves to null, the resulting Mono completes empty.

延迟:

public static Mono defer(Supplier> supplier)

Create a Mono provider that will supply a target Mono to subscribe to for each Subscriber downstream.

您能否解释一下两者是否都可以用于此要求以及它们之间的确切区别是什么?

Mono.defer 通常在您已经从第三方来源获得 Mono 时使用,但您希望将其创建延迟到订阅时间,因为在创建期间急切地完成了一些事情。

考虑以下示例:

public static void main(String[] args)
{
    callExternalService()
            .repeat(3)
            .subscribe();
}

private static Mono<?> callExternalService()
{
    System.out.println("External service is called.");

    return Mono.just("result");
}

乍一看,你会认为这个例子没有问题,但当你检查输出时,你会发现 External service is called 只打印了一次,而不是预期的四次(一个原始 + 三个重复)因为它是在 returned Mono.

的范围之外执行的

但是,如果你defer执行了Mono,它会按预期打印四次:

Mono.defer(() -> callExternalService())
    .repeat(3)
    .subscribe();

defer 的另一个用例是当您想要测试 repeat/retry/re-subscribe 逻辑并且您希望为模拟服务提供不同的 return 值时 returns Mono.

总而言之,它确实与 fromCallable 非常相似,但主要用于当您已经有一个方法 return 是 Mono 并且做一些急切的事情时。如果您可以完全控制代码,那么 fromCallable.

完全没问题