英文:
what the difference between handle and create?
问题
Article background
我正在尝试弄清楚handle
和create
之间的区别;
我已经参考了官方反应器文档,但官方提供的示例未能帮助我理解handle
和create
之间的差异。
handle
示例
Flux<String> alphabet = Flux.just(-1, 30, 13, 9, 20)
.handle((i, sink) -> {
String letter = alphabet(i);
if (letter != null)
sink.next(letter);
});
alphabet.subscribe(System.out::println);
create
示例
Flux<String> bridge = Flux.create(sink -> {
myEventProcessor.register(
new MyEventListener<String>() {
public void onDataChunk(List<String> chunk) {
for(String s : chunk) {
sink.next(s);
}
}
public void processComplete() {
sink.complete();
}
});
});
以上两个示例都来自官方反应器文档,显然,它们都使用了sink
操作,用于逐个生成数据(不确定,也对此感到困惑),那么当我们需要生成数据时,是否只需使用create
而不是handle
?
Main Question
最后,我总结了以下问题:
-
是否每次都可以使用
create
而不是handle
? -
在上述两个操作中是否有最佳实践或用法?
-
操作
sink
是否逐步生成数据? -
如果我在
sink.next()
之前在代码中执行一些IO操作,它会阻塞直到IO完成吗?这会导致下游阻塞吗?
英文:
Article background
i am trying to figure out that the difference betweenhandle
and create
;
i had refer to the reactor offical documents , but the sample which offical provided , could not point me to understand the diff with handle and create
- The
handle
sample
Flux<String> alphabet = Flux.just(-1, 30, 13, 9, 20)
.handle((i, sink) -> {
String letter = alphabet(i);
if (letter != null)
sink.next(letter);
});
alphabet.subscribe(System.out::println);
- The
create
sample
Flux<String> bridge = Flux.create(sink -> {
myEventProcessor.register(
new MyEventListener<String>() {
public void onDataChunk(List<String> chunk) {
for(String s : chunk) {
sink.next(s);
}
}
public void processComplete() {
sink.complete();
}
});
});
both sample above are from reactor offical documents , obviously , both of them have the operation sink
that used to generate one by one (not sure , also have confusion in it ) , so the handle
is not necessary when we need to generate datas , just use create
instead of ``handle``` ?;
Main Question
Finally , i have collect the question in summary
-
Could use the
create
instead ofhandle
every time?
is there some best practice or useage in both of the operation above? -
Is it generate data step-by-step with the operation
sink
?
if i have some IO operate in code beforesink.nest()
, it will block util the IO complate? so that is it will block for thw dowstream?
答案1
得分: 0
虽然这些示例产生了相似的结果,Flux.create
与 handle
有不同的用途。
Flux.create
可用于通过发射多个元素来创建一个 Flux
。
上面的代码与 Flux.range(0, 3)
相同;
handle
用于在流程的一部分处理数据。handle
的最接近类似物是 map
。你可以将其视为 map
和 filter
的组合。与 flatMap
不同,handle
和 map
都是同步函数。
map
- 通过应用同步函数来转换发射的项目。它提供1:1的映射,每个项目都应该被映射。跳过项目的唯一方式是抛出异常,然后立即处理错误信号使用 onErrorResume
。
handle
- 更灵活,提供0或1的映射。可以通过不发射信号来跳过项目,使用 sink.next()
。
在您的情况下,没有必要将用户包装成 Mono
并使用 flatMap
。使用 map
,因为映射是1:1的。
英文:
Although these samples produce similar results Flux.create
has a different purpose that handle
.
Flux.create
could be used to create a Flux
by emitting multiple elements.
@Test
void fluxCreateRange() {
Flux<Integer> range = Flux.create(emitter -> {
FluxSink<Integer> sink = emitter.next(0);
for (int i = 1; i <= 3; i++) {
sink.next(i);
}
sink.complete();
});
StepVerifier.create(range)
.expectNext(0, 1, 2, 3)
.verifyComplete();
}
The above code is the same as Flux.range(0, 3)
;
handle
is used to process data as a part of the flow. The closest analog of the handle
is a map
. You could think about it as a combination of the map
& filter
. In contrast to flatMap
both handle
and map
are synchronous function.
map
- transforms the emitted item by applying a synchronous function. It provides 1:1 mapping and every item should be mapped. The only way to skip item is to throw exception and then immediately handle the error signal using onErrorResume
.
handle
- is more flexible and provides 0 or 1 mapping. It's possible to skip items by not emitting signal using sink.next()
.
In your case there is no reason to wrap user into Mono
and use flatMap
. Use map
because mapping is 1:1.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论