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

14
我通常需要生成一个Mono / Flux,其值将在订阅时生成/计算。对于这个需求,fromCallable和defer运算符似乎都可以胜任。
我无法清楚地看到javadoc中的区别:
FromCallable: public static Mono fromCallable(Callable supplier)
使用提供的Callable创建产生其值的Mono。 如果Callable解析为null,则生成的Mono完成为空。
Defer: public static Mono defer(Supplier> supplier)
创建一个Mono提供程序,该程序将向每个Subscriber下游提供订阅的目标Mono。
您能否解释一下是否可以同时使用两种方法来满足此要求以及它们之间的确切区别?
1个回答

22

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只被打印了一次,而不是期望的四次(一个原始和三个重复),因为它在返回的Mono的范围之外执行。

然而,如果您延迟执行Mono,它将像预期的那样打印四次:

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

defer 的另一个用例是当您想要测试重复/重试/重新订阅逻辑并且希望对返回 Mono 的模拟服务具有不同的返回值时。

总之,它确实非常类似于 fromCallable,但通常在您已经有一个返回 Mono 并且执行一些急切操作的方法时使用。如果您对代码完全掌控,则可以完全使用 fromCallable


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接