Geração de fontes de dados do reator

Flux e Mono são usados ​​como fontes de dados. Há muitas maneiras de gerar dados. Este artigo lista e descreve resumidamente os métodos comumente usados. Lugares insuficientes podem ir para o documento de origem para visualização.

Fonte de dados vazia ou fonte de dados especial

vazio

Com o método vazio, um fluxo de dados vazio pode ser criado.

Flux.empty();
Mono.empty();

erro

Com o método de erro, um fluxo de dados incorreto pode ser criado.

Flux.error(new RuntimeException("error"));
Mono.error(new RuntimeException("error"));

nunca

Com o método never, você pode criar um fluxo de dados que nunca emitirá nenhum sinal.

Flux.never();
Mono.never();

fonte de dados simples

apenas

Com o método just, você pode criar um fluxo de dados que contém elementos fixos.

Flux.just("foo", "bar", "foobar");
Mono.just("foo");

faixa

Com o método range, você pode criar um fluxo de dados que contém um intervalo especificado de números inteiros.

FLux<Integer> flux = Flux.range(1, 10);

fromArray

Por meio do método fromArray, você pode criar um fluxo de dados contendo os elementos do array.

Flux.fromArray(new Integer[]{
    
    1, 2, 3});

fromIterable

Por meio do método fromIterable, você pode criar um fluxo de dados contendo elementos Iterable.

Flux.fromIterable(Arrays.asList("foo", "bar", "foobar"));

fromStream

Por meio do método fromStream, você pode criar um fluxo de dados que contém elementos Stream.

Flux.fromStream(Stream.of("foo", "bar", "foobar"));

do futuro

Por meio do método fromFuture, um fluxo de dados contendo elementos CompletableFuture pode ser criado.

Mono.fromFuture(CompletableFuture.completedFuture("foo"));

fromRunnable

Por meio do método fromRunnable, você pode criar um fluxo de dados contendo elementos Runnable.

Mono.fromRunnable(() -> System.out.println("foo"));

Intervalo gera tempo de intervalo para enviar dados

intervalo

Com o método interval, você pode criar um fluxo de dados que envia elementos em intervalos regulares.

Flux.interval(Duration.ofSeconds(1));

intervaloMilis

Com o método intervalMillis, você pode criar um fluxo de dados que envia elementos em intervalos regulares.

Flux.intervalMillis(1000);

Métodos avançados geram e criam

gerar

Por meio do método generate, você pode personalizar a geração de fluxos de dados. O método generate gera elementos de forma síncrona, um por vez. Isso significa que quando um elemento é consumido, o próximo elemento será produzido. O coletor é um SynchronousSink que fornece o método next() para gerar elementos.

generate tem vários métodos sobrecarregados.

Flux.generate(generator);
Flux.generate(stateSupplier,generator);
/**
 * @param stateSupplier 一个无参函数,返回一个初始状态
 * @param generator 一个BiFunction,接受状态和SynchronousSink,返回新的状态
 * @param stateConsumer 一个Consumer,接受状态,用于清理资源
 */
Flux.generate(stateSupplier,generator,stateConsumer)

A demonstração específica é a seguinte:


Flux.generate(sink->{
    
    
        sink.next("Hello");
        sink.complete();
});
        
Flux.generate(()->0,(state,sink)->{
    
    
        sink.next("3 x "+state+" = "+3*state);
        if(state==10)sink.complete();
        return state+1;
});

criar

Por meio do método create, você pode personalizar a geração de fluxos de dados. O método create é mais avançado do que o método generate.Ele pode gerar um elemento por vez de forma síncrona ou vários elementos por vez de forma assíncrona. Este método usa o FluxSink, que também fornece os métodos next, error e
complete. Ao contrário de generate, create não requer um valor de estado, por outro lado, pode disparar vários eventos no callback (mesmo em algum momento no futuro).

        //create方法的接口
        Flux.create(Consumer<? super FluxSink<T>>emitter)


        /**
         *
         */
        Flux.create(Consumer<? super FluxSink<T>>emitter,FluxSink.OverflowStrategy overflowStrategy)

Supondo que você tenha uma API de ouvinte que processe dados por bloco, há dois tipos de eventos: (1) um evento de dados de bloco pronto; (2) evento de fim de processamento. do seguinte modo:

interface MyEventListener<T> {
    
    
    void onDataChunk(List<T> chunk);

    void processComplete();
}

Você pode implementar essa API usando o método create:

Flux.create(sink->{
    
    
        MyEventListener<T> listener=new MyEventListener<T>(){
    
    
            @Override
            public void onDataChunk(List<T> chunk){
    
    
                for(T value:chunk){
    
    
                    sink.next(value);
                }
            }
            @Override
            public void processComplete(){
    
    
                sink.complete();
            }
        };
        source.register(listener);
});

Além disso, como create pode ser assíncrono e controlado por backpressure, você pode definir o comportamento de backpressure fornecendo um OverflowStrategy.

  • IGNORE: ignora completamente as solicitações de contrapressão downstream, o que pode causar uma IllegalStateException se a fila downstream ficar cheia.
  • ERRO: Um IllegalStateException é sinalizado quando o downstream não consegue acompanhar.
  • DROP: Descarte este elemento quando o downstream não estiver pronto para receber um novo elemento.
  • LATEST: Deixe o downstream obter apenas os elementos mais recentes do upstream.
  • BUFFER: (padrão) armazena em buffer todos os elementos que não foram processados ​​a jusante (esse buffer de tamanho ilimitado pode causar OutOfMemoryError).

modo push

No modo push, a fonte de dados enviará dados ativamente para o downstream. Nesse modo, a fonte de dados é o produtor e o downstream é o consumidor. Uma variante de create é push, adequada para gerar fluxos de eventos. Criar 类似,push também pode ser assíncrono e pode usar as estratégias de estouro acima (
estratégias de estouro) para gerenciar a contrapressão. Apenas um thread de spawn pode chamar next, complete ou error por vez.

Flux<String> bridge=Flux.push(sink->{
    
    
        myEventProcessor.register(new SingleThreadEventListener<String>(){
    
    
            public void onDataChunk(List<String> chunk){
    
    
                for(String s:chunk){
    
    
                    sink.next(s);
                }
            }
            public void processComplete(){
    
    
                sink.complete();
            }
            public void processError(Throwable e){
    
    
            sink.error(e);
            }
        });
});

Modo híbrido empurrar/puxar (empurrar/puxar)

Ao contrário de push, create pode ser usado no modo push ou pull, portanto, é adequado para APIs de ouvinte de ponte, porque as mensagens de evento virão de forma assíncrona a qualquer momento. O método de retorno de chamada onRequest pode ser registrado no FluxSink
para rastrear solicitações. Esse retorno de chamada pode ser usado para solicitar mais dados da origem ou para gerenciar a contrapressão passando os dados para o coletor quando chega uma solicitação downstream. Este é um padrão push/pull híbrido, porque o downstream pode extrair dados prontos do upstream, e o upstream também pode enviar os dados para o downstream quando estiver pronto.

Flux<String> bridge = Flux.create(sink -> {
    
    
    myMessageProcessor.register(
      new MyMessageListener<String>() {
    
    

        public void onMessage(List<String> messages) {
    
    
          for(String s : messages) {
    
    
            sink.next(s); 
          }
        }
    });
    sink.onRequest(n -> {
    
    
        List<String> messages = myMessageProcessor.request(n); 
        for(String s : message) {
    
    
           sink.next(s); 
        }
    });

No artigo acima, formas e métodos comuns de geração de fontes de dados são desmontados e listados. Apenas para a conveniência de uma melhor entrada e compreensão, o rigor e a integridade são difíceis de garantir. Se você quiser estudar mais ou sentir que há uma falácia, acesse o site oficial para obter mais informações.

Acho que você gosta

Origin blog.csdn.net/aofengdaxia/article/details/128906288
Recomendado
Clasificación