【发布时间】:2019-09-30 14:19:48
【问题描述】:
有人可以帮我理解以下之间的区别:
Mono.defer()Mono.create()Mono.just()
如何正确使用?
【问题讨论】:
标签: spring-webflux project-reactor
有人可以帮我理解以下之间的区别:
Mono.defer()Mono.create()Mono.just()如何正确使用?
【问题讨论】:
标签: spring-webflux project-reactor
Mono.just(value) 是最原始的——一旦你有了一个值,你就可以把它包装成一个 Mono 并且订阅者会得到它。
Mono.defer(monoSupplier) 允许您提供整个表达式来提供结果 Mono 实例。这个表达式的评估被推迟到有人订阅。在此表达式中,您还可以使用Mono.error(throwable) 之类的控制结构来指示错误条件(您不能使用Mono.just 执行此操作)。
Mono.create(monoSinkConsumer) 是最先进的方法,可让您完全控制发出的值。无需从回调中返回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 的回答,但我会谨慎对待建议
一般建议是使用最不强大的抽象来完成这项工作:
Mono.just->Mono.defer->Mono.create。
在反应式方法中,特别是如果我们是初学者,很容易忽略“最不强大的抽象”实际上是哪个。除了@IlyaZinkovich,我没有说别的,只是描述了一个细节方面。
我想添加一个特定用例,其中Mono.defer() 比Mono.just() 更可取,但乍一看可能看不到这一事实。
我们使用switchIfEmpty() 作为订阅时间分支:
// First ask provider1
provider1.provide(someData)
// If provider1 did not provide the result, ask the fallback provider provider2
.switchIfEmpty(provider2.provide(someData))
provider2.provide() 仅当provider1.provide() 不返回任何结果时才接受someData,和/或provider2.provide() 返回的Mono 的方法组合可能很昂贵,甚至失败当调用错误的数据时。
这种情况defer() 更可取,即使它可能乍一看还不清楚:
provider1.provide(someData)
// ONLY IF provider1 did not provide the result, assemble another Mono with provider2.provide()
.switchIfEmpty(Mono.defer(() -> provider2.provide(someData)))
【讨论】: