Mono.Defer() vs Mono.create() vs Mono.just()?

Mono.Defer() vs Mono.create() vs Mono.just()?

有人可以帮助我理解以下两者之间的区别:

如何正确使用?

Mono.just(value) 是最原始的——一旦你有了一个值,你就可以将它包装到一个 Mono 中,然后订阅者就会得到它。

Mono.defer(monoSupplier) 允许您提供提供结果 Mono 实例的整个表达式。这个表达式的评估被推迟,直到有人订阅。在此表达式内,您还可以使用 Mono.error(throwable) 等控制结构来指示错误条件(您不能使用 Mono.just 执行此操作)。

Mono.create(monoSinkConsumer) 是最先进的方法,可让您完全控制发出的值。无需从回调中 return Mono 实例(如 Mono.defer 中),您可以控制 MonoSink<T> 让您通过 MonoSink.success() 发出值, MonoSink.success(value), MonoSink.error(throwable) 方法。 Reactor 文档包含一些可能的 Mono.create 用例的好例子:link to doc.

一般建议是使用功能最弱的抽象来完成这项工作:Mono.just -> Mono.defer -> Mono.create

虽然大体上我同意(并称赞)@IlyaZinkovich 的回答,但我会谨慎对待这些建议

The general advice is to use the least powerful abstraction to do the job: Mono.just -> Mono.defer -> Mono.create.

在反应式方法中,特别是如果我们是初学者,很容易忽略“最不强大的抽象”实际上是什么。除了@IlyaZinkovich,我什么都没说,只是描述了一个详细的方面。

这是一个特定的用例,其中 更强大的 抽象 Mono.defer()Mono.just() 更可取,但乍一看可能不可见。

另请参阅:

我们使用switchIfEmpty()作为subscription-time branching:

// First ask provider1
provider1.provide1(someData)
    // If provider1 did not provide the result, ask the fallback provider provider2
    .switchIfEmpty(provider2.provide2(someData))

public Mono<MyResponse> provide2(MyRequest someData) {
    // The Mono assembly is needed only in some corner cases
    // but in fact it is always happening
    return Mono.just(someData)
        // expensive data processing which might even fail in the assemble time
        .map(...)
        .map(...)
        ...
}

provider2.provide2()仅在provider1.provide1()没有return任何结果时才接受someDataand/or方法由 provider2.provide2() 编辑的 Mono return 的汇编非常昂贵,甚至在调用错误数据时失败。

在这种情况下 defer() 更可取,即使它 可能 乍一看并不明显:

provider1.provide1(someData)
    // ONLY IF provider1 did not provide the result, assemble another Mono with provider2.provide()
    .switchIfEmpty(Mono.defer(() -> provider2.provide2(someData)))