(12)自定义数据流(实战Docker事件推送的REST API)——响应式Spring的道法术器

本系列其他文章见:《响应式Spring的道法术器》
前情提要:响应式流 | Reactor3快速上手 | 深入理解响应式流规范

2.2 自定义数据流

这一小节介绍如何通过定义相应的事件(onNextonErroronComplete) 创建一个 Flux 或 Mono。Reactor提供了generatecreatepushhandle等方法,所有这些方法都使用 sink(池)来生成数据流。

sink,顾名思义,就是池子,可以想象一下厨房水池的样子。如下图所示:

下面介绍到的方法都有一个sink提供给方法使用者,通常至少会暴露三个方法给我们,nexterrorcomplete。next和error相当于两个下水口,我们不断将自定义的数据放到next口,Reactor就会帮我们串成一个Publisher数据流,直到有一个错误数据放到error口,或按了一下complete按钮,数据流就会终止了。

本文测试源码

2.2.1 generate

generate是一种同步地,逐个地发出数据的方法。因为它提供的sink是一个SynchronousSink, 而且其next()方法在每次回调的时候最多只能被调用一次。

generate方法有三种签名:

    public static <T> Flux<T> generate(Consumer<SynchronousSink<T>> generator)
    
    public static <T, S> Flux<T> generate(Callable<S> stateSupplier, BiFunction<S, SynchronousSink<T>, S> generator) 
    
    public static <T, S> Flux<T> generate(Callable<S> stateSupplier, BiFunction<S, SynchronousSink<T>, S> generator, Consumer<? super S> stateConsumer)

1)使用SynchronousSink生成数据流

    @Test
    public void testGenerate1() {
   
        final AtomicInteger count = new AtomicInteger(1);   // 1
        Flux.generate(sink -> {
   
            sink.next(count.get() + " : " + new Date());   // 2
            try {
   
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            if (count.getAndIncrement() >= 5) {
   
                sink.complete();     // 3
            }
        }).subscribe(System.out::println);  // 4
    }
  1. 用于计数;
  2. 向“池子”放自定义的数据;
  3. 告诉generate方法,自定义数据已发完;
  4. 触发数据流。

输出结果为每1秒钟打印一下时间,共打印5次。

2)增加一个伴随状态

对于上边的例子来说,count用于记录状态,当值达到5之后就停止计数。由于在lambda内部使用,因此必须是final类型的,且不能是原生类型(如int)或不可变类型(如Integer)。

如果使用第二个方法签名,上边的例子可以这样改:

    @Test
    public void testGenerate2() {
   
        Flux.generate(
                () -> 1,    // 1
                (count, sink) -> {
         // 2
                    sink.next(count + " : " + new Date());
                    try {
   
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }
                    if (count >= 5) {
   
                        sink.complete();
                    }
  
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值