Mono.Defer() vs Mono.create() vs Mono.just()?
Mono.Defer() vs Mono.create() vs Mono.just()?
有人可以帮助我理解以下两者之间的区别:
Mono.defer()
Mono.create()
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任何结果时才接受someData
,and/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)))
有人可以帮助我理解以下两者之间的区别:
Mono.defer()
Mono.create()
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任何结果时才接受someData
,and/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)))