handle 和 create 之间的区别是什么?

huangapple go评论149阅读模式
英文:

what the difference between handle and create?

问题

Article background

我正在尝试弄清楚handlecreate之间的区别;
我已经参考了官方反应器文档,但官方提供的示例未能帮助我理解handlecreate之间的差异。

  • 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 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 of handle 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 before sink.nest() , it will block util the IO complate? so that is it will block for thw dowstream?

答案1

得分: 0

虽然这些示例产生了相似的结果,Flux.createhandle 有不同的用途。

Flux.create 可用于通过发射多个元素来创建一个 Flux

上面的代码与 Flux.range(0, 3) 相同;

handle 用于在流程的一部分处理数据。handle 的最接近类似物是 map。你可以将其视为 mapfilter 的组合。与 flatMap 不同,handlemap 都是同步函数。

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.

huangapple
  • 本文由 发表于 2023年3月7日 14:10:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75658539.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定