英文:
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 betweenhandleand 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
handlesample
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
createsample
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
createinstead ofhandleevery 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论