02-Quarkus-Multi和Uni

Quarkus Reactive API

我们上一章创建了一个简单的HelloWorld项目,非常的简单并没有什么响应式编程的内容,既然Quarkus是支持响应式编程的,那我们今天先看一下Quaruks提供的响应式编程API。

2021-01-12 补充

最近一直忙于Coding,没有时间按计划写下面的文章。但是通过最近工作发现,除了熟悉Quarkus各种组件的工作方式外,比较重要的还是这里的Multi和Uni原理和API的使用,原理这个东西不太好说,但是使用经验可以在后期有时间的时候将最近一段时间API 的使用心得单独整理一遍文章吧。

本章目标:

  • 学习使用Quarkus实现的响应式编程库
  • io.smallrye.mutiny.Uni
  • io.smallrye.mutiny.Multi

一 Quarkus 框架响应式处理原理

Quarkus响应式基础架构
由上图可以看到Quarkus底层是由Vertx来调度应用的请求处理和响应,无论我们的应用是响应式的还是阻塞式的。当然为了更高的性能,Quarkus当然建议我们使用响应式的API来实现我们的应用。下面看一下响应式应用和同步应用的调度区别。
同步应用

同步应用的路由调用是由应用工作线程来执行的。
响应式应用
可以看到响应式的应用是路由层直接调用IO线程来执行,这样会有更高的并发。

二 Multi和Uni

1 引入依赖
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-mutiny</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-resteasy-jackson</artifactId>
        </dependency>

因为我们基于一个Rest服务来学习,所以加入了一些其他依赖。其实今天的主角是quarkus-resteasy-mutiny

2 Quakus 提供的两个核心异步编程库

*io.smallrye.mutiny.Uni - 提供0或者一个结果的异步操作
*io.smallrye.mutiny.Multi -提供多个结果的异步操作

我们通过几个接口来尝试一下异步操作。

2.1 Uni<?>

我们写一个简单的返回字符串的例子:

@GET
@Path("uni_test1")
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> uni_test(){

    return Uni.createFrom().item("uni");
}

访问接口: curl http://127.0.0.1:8080/rx/uni_test1
Uni 返回值
通过上面的简单例子可以看出构建一个Uni结果还是比较简单的, 同时Uni还提供了非常丰富的操作来构建Uni,接下来我们详细看一下Uni的常用API。
Uni 是一个接口,但是提供了两个静态的方法来快速创建一个Uni。
Uni 静态方法

  • combine() 是联合其他的Uni返回一个组合的Uni
  • createFrom() 见名知意从from中来创建Uni 这里的From是什么呢? 我们来看UniCreate这个返回值。
  • 从UniCreate类中看到,这个类是整合了所有Uni支持的创建方式

创建Uni的方式
我们就几个比较常用的创建方式测试一下:

  • item(Supplier) 如果大家对函数式编程不是很理解,可以着重去看下函数式编程。
    @GET
    @Path("uni_test2")
    @Produces(MediaType.TEXT_PLAIN)
    public Uni<String> uni_test2(){
        return Uni.createFrom().item(()->{return "hello uni";});
    }

结果:
test2 结果

  • completionStage
@GET
@Path("uni_test3")
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> uni_test3(){

    return Uni.createFrom().completionStage(CompletableFuture
            .supplyAsync(()->"hello ")
            .thenApply(str->{return str + "completeStage";}));
}

结果:
completestage结果

  • failure
@GET
@Path("uni_test4")
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> uni_test4(){
    return Uni.createFrom().failure(RuntimeException::new);
}

结果:
failure
当然我们开发中肯定不能这么干,我们需要基于事件做异常处理。

  • multi multi后面会讲,这里说的是从Multi中创建Uni对象但只是从Multi中取第一个item
    @GET
    @Path("uni_test5")
    @Produces(MediaType.TEXT_PLAIN)
    public Uni<String> uni_test5(){

        return Uni.createFrom().multi(Multi
                                        .createFrom()
                                        .items(Stream.of("1", "2")));
    }

结果:
在这里插入图片描述
这里先讲这几个常用API,其实Api的使用方式非常简单,关键还是要熟悉Java中函数式和响应式编程的方式。

2.2 Multi

跟Uni一致,Multi也提供了两个快速创建Multi的静态方法。
创建Multi静态方法

  • createFrom 类似UniCreate,封装了创建Multi的方式
  • createBy 类似combine 是聚合或者连接两个Multi的
    我们还是只看createFrom
    创建Multi方式
  • Item
@GET
@Path("multi_test1")
@Produces(MediaType.APPLICATION_JSON)
public Multi<String> multi_test1(){

    return Multi.createFrom().items(Stream.of("1", "2", "3"));
}

结果:
multi string
这里需要注意的是Multi本身就代表了一个列表。如果我们item中放入的是一个list,那么返回值类型就是Multi<List> 结果就是 [[1,2,3,]]这种形式。
其他的API 跟 Uni类似,后面就不再一一测试了。

以上仅仅是介绍了创建Uni和Multi的方式,下面还有一些API 如 转换、事件处理等。

2.3 事件处理

响应式编程的实现中一般都是基于订阅模式,提供基于事件驱动的API,Quarkus同样也是基于此实现。那何为事件驱动,就是在流程中出现一些事件节点如数据准备好了、报错了或者超时了等等事件,在事件后面加上事件的处理逻辑。
事件
这些方法都可以认为是事件方法,在一定条件下会触发,然后执行后面的逻辑。

2.4 转换

Uni和Multi或者其他类型的转换。

  • Uni和Multi之间或自己转换 transformToXXX 类似于Java中的flatMap
    在这里插入图片描述
  • 转换成其他类型
    在这里插入图片描述
Maybe<String> maybe = uni.convert().with(UniRxConverters.toMaybe());
Flux<String> flux = multi.convert().with(MultiReactorConverters.toFlux());

三 总结

  • Quarkus提供的响应式开发库主要分为两类: Uni 和 Mult
  • Api类型大致分为三类 创建数据、事件方法、转换方法
  • 核心还是Java的函数式编程和异步编程
UniApp 的 multi-select 功能是指在一个界面中提供一个多选列表,用户可以从中选择多个选项。在 UniApp 开发中,为了实现这个功能,你可以利用其内置的组件库,如 `u-picker` 或者自定义组件结合 `picker-column` `picker-items` 来构建。 以下是一个简单的步骤说明: 1. 引入依赖:在你的 Vue 文件中,首先需要引入 `uni-picker` 组件: ```html <template> <!-- ... --> </template> <script setup> import { picker } from '@vant/components'; </script> ``` 2. 创建 multi-select 组件: ```html <van-picker v-model="selectedValues" :columns="columns" @change="onChange"> <van-picker-column title="请选择" value-key="value"> <!-- 这里是你的选项数据数组,每个选项都有 'value' 'label' 属性 --> <template v-for="(item, index) in options" :key="index"> <van-picker-item :value="item.value" :label="item.label"></van-picker-item> </template> </van-picker-column> </van-picker> ``` 3. 初始化状态处理函数: ```js const selectedValues = ref([]); const columns = [ { title: '标题', values: options, // 你的选项数据数组 } ]; function onChange(values) { selectedValues.value = values; // 根据需要处理选中的值 } // 你需要定义 options 数组,例如: const options = [ { value: 'option1', label: '选项1' }, { value: 'option2', label: '选项2' }, { value: 'option3', label: '选项3' }, // 更多选项... ]; ``` 4. 当你需要获取用户选择的值时,可以直接使用 `selectedValues` 变量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值