当前位置: 首页 > news >正文

响应式编程Reactor优化Callback回调地狱

1. Reactor是什么

  • Reactor 是一个基于Reactive Streams规范的响应式编程框架。它提供了一组用于构建异步、事件驱动、响应式应用程序的工具和库。Reactor 的核心是 Flux(表示一个包含零到多个元素的异步序列)和 Mono表示一个包含零或一个元素的异步序列)。
  • Reactor 通过提供响应式的操作符,如mapfilterflatMap等,使得开发者能够方便地进行数据流的转换和处理。

2. Reactor、Callback、CompletableFuture三种形式异步编码对比

  • 编码简洁程度Reactor最优
  • Reactor线程利用率最高(因实现了Reactive Streams规范,拥有背压+事件驱动特性,此处暂不展开)

代码如下:

pom依赖

<dependencyManagement><dependencies><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-bom</artifactId><version>2023.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><dependencies><dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId></dependency>
</dependencies>

Callback回调地狱

interface FirstCallback {void onCompleteFirst(String result);void onErrorFirst(Exception e);
}interface SecondCallback {void onCompleteSecond(String result);void onErrorSecond(Exception e);
}interface ThirdCallback {void onCompleteThird(String result);void onErrorThird(Exception e);
}class AsyncOperations {static void firstOperation(FirstCallback firstCallback) {new Thread(() -> {try {// 模拟异步操作Thread.sleep(2000);// 操作完成后调用回调函数firstCallback.onCompleteFirst("First operation completed");} catch (Exception e) {// 发生异常时调用错误回调firstCallback.onErrorFirst(e);}}).start();}static void secondOperation(String input, SecondCallback secondCallback) {new Thread(() -> {try {// 模拟异步操作Thread.sleep(2000);// 操作完成后调用回调函数secondCallback.onCompleteSecond("Second operation completed with input: " + input);} catch (Exception e) {// 发生异常时调用错误回调secondCallback.onErrorSecond(e);}}).start();}static void thirdOperation(String input, ThirdCallback thirdCallback) {new Thread(() -> {try {// 模拟异步操作Thread.sleep(2000);// 操作完成后调用回调函数thirdCallback.onCompleteThird("Third operation completed with input: " + input);} catch (Exception e) {// 发生异常时调用错误回调thirdCallback.onErrorThird(e);}}).start();}
}public class CallbackHellExample {public static void main(String[] args) {AsyncOperations.firstOperation(new FirstCallback() {@Overridepublic void onCompleteFirst(String result) {System.out.println("First Callback: " + result);// 第一次操作完成后调用第二次操作AsyncOperations.secondOperation(result, new SecondCallback() {@Overridepublic void onCompleteSecond(String result) {System.out.println("Second Callback: " + result);// 第二次操作完成后调用第三次操作AsyncOperations.thirdOperation(result, new ThirdCallback() {@Overridepublic void onCompleteThird(String result) {System.out.println("Third Callback: " + result);}@Overridepublic void onErrorThird(Exception e) {System.out.println("Error in Third Callback: " + e.getMessage());}});}@Overridepublic void onErrorSecond(Exception e) {System.out.println("Error in Second Callback: " + e.getMessage());}});}@Overridepublic void onErrorFirst(Exception e) {System.out.println("Error in First Callback: " + e.getMessage());}});// 主线程继续执行其他操作System.out.println("Main thread continues...");}
}

CompletableFuture优化Callback回调地狱

public class CompletableFutureExample {public static void main(String[] args) {CompletableFuture<String> firstOperation = CompletableFuture.supplyAsync(() -> {try {// 模拟异步操作Thread.sleep(2000);return "First operation completed";} catch (InterruptedException e) {throw new RuntimeException(e);}});CompletableFuture<String> secondOperation = firstOperation.thenApplyAsync(result -> {System.out.println("First CompletableFuture: " + result);try {// 模拟异步操作Thread.sleep(2000);return "Second operation completed with input: " + result;} catch (InterruptedException e) {throw new RuntimeException(e);}});CompletableFuture<String> thirdOperation = secondOperation.thenApplyAsync(result -> {System.out.println("Second CompletableFuture: " + result);try {// 模拟异步操作Thread.sleep(2000);return "Third operation completed with input: " + result;} catch (InterruptedException e) {throw new RuntimeException(e);}});thirdOperation.whenComplete((result, throwable) -> {if (throwable == null) {System.out.println("Third CompletableFuture: " + result);} else {System.out.println("Error in CompletableFuture: " + throwable.getMessage());}});// 主线程继续执行其他操作System.out.println("Main thread continues...");// 等待所有操作完成CompletableFuture.allOf(firstOperation, secondOperation, thirdOperation).join();}
}

Reactor优化Callback回调地狱

public class ReactorOptimizedExample {public static void main(String[] args) {Mono.fromCallable(() -> {// 模拟异步操作Thread.sleep(2000);return "First operation completed";}).subscribeOn(Schedulers.boundedElastic()).flatMap(result -> {System.out.println("First Reactor: " + result);return Mono.fromCallable(() -> {// 模拟异步操作Thread.sleep(2000);return "Second operation completed with input: " + result;}).subscribeOn(Schedulers.boundedElastic());}).flatMap(result -> {System.out.println("Second Reactor: " + result);return Mono.fromCallable(() -> {// 模拟异步操作Thread.sleep(2000);return "Third operation completed with input: " + result;}).subscribeOn(Schedulers.boundedElastic());}).doOnSuccess(result -> System.out.println("Third Reactor: " + result)).doOnError(error -> System.out.println("Error in Reactor: " + error.getMessage())).block(); // 阻塞等待操作完成// 主线程继续执行其他操作System.out.println("Main thread continues...");}
}

学习打卡:Java学习笔记-day06-响应式编程Reactor优化Callback回调地狱

相关文章:

响应式编程Reactor优化Callback回调地狱

1. Reactor是什么 Reactor 是一个基于Reactive Streams规范的响应式编程框架。它提供了一组用于构建异步、事件驱动、响应式应用程序的工具和库。Reactor 的核心是 Flux&#xff08;表示一个包含零到多个元素的异步序列&#xff09;和 Mono表示一个包含零或一个元素的异步序列…...

React项目实战--------极客园项目PC端

项目介绍&#xff1a;主要将学习到的项目内容进行总结&#xff08;有需要项目源码的可以私信我&#xff09; 关于我的项目的配置如下&#xff0c;请注意下载的每个版本不一样&#xff0c;写的api也不一样 一、项目介绍 1.资料 1&#xff09;短信接收&M端演示&#xff1a…...

Jerry每次能向前或向后走n*n步(始终不能超过初始位置1e5),q(q <= 1e5)次询问,求向前走d最少要几次

题目 思路&#xff1a;因为有走的过程不能超初始位置1e5的限制&#xff0c;所以不能直接用奇数最多两次&#xff0c;4的倍数最多两次的结论。spfa&#xff0c;平方数的dis为1&#xff0c;然后推出其他数的dis #include<bits/stdc.h> using namespace std; #define int …...

【Spring Boot 3】【Flyway】数据库版本管理

【Spring Boot 3】【Flyway】数据库版本管理 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是…...

蓝桥杯基础数据结构(java版)

引言 数据结构数据结构。所以数据结构是一个抽象的概念。其目的是为了更好的组织数据方便数据存储。下面我们来看一些简单的数据储存方式 输入和输出 这里先介绍java的输入和输出。简单引入&#xff0c;不过多详细介绍&#xff0c;等我单一写一篇的时候这里会挂上链接 简单的…...

39 C++ 模版中的参数如果 是 vector,list等集合类型如何处理呢?

在前面写的例子中&#xff0c;模版参数一般都是 int&#xff0c;或者一个类Teacher&#xff0c;假设我们现在有个需求&#xff1a;模版的参数要是vector&#xff0c;list这种结合类型应该怎么写呢&#xff1f; //当模版中的类型是 vector &#xff0c;list 等集合类型的时候的处…...

5.Pytorch模型单机多GPU训练原理与实现

文章目录 Pytorch的单机多GPU训练1)多GPU训练介绍2)pytorch中使用单机多GPU训练DistributedDataParallel(DDP)相关变量及含义a)初始化b)数据准备c)模型准备d)清理e)运行 3)使用DistributedDataParallel训练模型的一个简单实例 欢迎访问个人网络日志&#x1f339;&#x1f339;知…...

想成为一名C++开发工程师,需要具备哪些条件?

C语言是一门面向过程的、抽象化的通用程序设计语言&#xff0c;广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能&#xff0c;但仍然保…...

Qat++,轻量级开源C++ Web框架

目录 一.简介 二.编译Oat 1.环境 2.编译/安装 三.试用 1.创建一个 CMake 项目 2.自定义客户端请求响应 3.将请求Router到服务器 4.用浏览器验证 一.简介 Oat是一个面向C的现代Web框架 官网地址&#xff1a;https://oatpp.io github地址&#xff1a;https://github.co…...

openssl3.2 - 官方demo学习 - digest - EVP_MD_demo.c

文章目录 openssl3.2 - 官方demo学习 - digest - EVP_MD_demo.c概述笔记END openssl3.2 - 官方demo学习 - digest - EVP_MD_demo.c 概述 使用 SHA3-512 对多个buffer连续进行摘要, 最后得到一个摘要值 笔记 /*! \file EVP_MD_demo.c \note openssl3.2 - 官方demo学习 - dig…...

uniapp 编译后文字乱码的解决方案

问题: 新建的页面中编写代码&#xff0c;其中数字和图片都可以正常显示&#xff0c;只有中文编译后展示乱码 页面展示也是乱码 解决方案: 打开HuilderX编辑器的【文件】- 【以指定编码重新打开】- 【选择UTF-8】 然后重新编译就可以啦~ 希望可以帮到你啊~...

iOS中利用KeyChain永久保存用户信息的方法示例

方法示例 一、新建一个LYKeychainTool类&#xff0c;导入系统Security框架 &#xff0c;LYKeychainTool.h文件实现如下 // // LYKeychainTool.h // keyChainTest // // Created by Liyu on 2017/6/2. // Copyright © 2017年 liyu. All rights reserved. //#import <F…...

基于时域有限差分法的FDTD的计算电磁学算法(含Matlab代码)-YEE网格下的更新公式推导

基于时域有限差分法的FDTD的计算电磁学算法&#xff08;含Matlab代码&#xff09;-YEE网格下的更新公式推导 参考书籍&#xff1a;The finite-difference time-domain method for electromagnetics with MATLAB simulations&#xff08;国内翻译版本&#xff1a;MATLAB模拟的电…...

win10使用debug,汇编初学

DOSBox挂载Debug.exe 双击 DOSBox Options.bat 打开配置 或者执行cmd DOSBox.exe -editconf notepad.exe -editconf %SystemRoot%\system32\notepad.exe -editconf %WINDIR%\notepad.exe最后一行增加 mount [盘符] [挂载的工作目录&#xff08;debug.exe文件夹位置&#xff…...

怎么投稿各大媒体网站?

怎么投稿各大媒体网站&#xff1f;这是很多写作者及自媒体从业者经常面临的问题。在信息爆炸的时代&#xff0c;如何将自己的文章推送到广大读者面前&#xff0c;成为了一个不可避免的挑战。本文将为大家介绍一种简单有效的投稿方法——媒介库发稿平台发稿&#xff0c;帮助大家…...

chatgpt免费使用的网站

前言 如果您认为本文对你有帮助&#xff0c;希望可以点赞收藏&#xff01;感谢您的支持 下面我为你推荐我自己在用的gpt类工具&#xff0c;帮你在工作学习生活上解决一些大小问题 &#x1f389;智能GPT 地址&#xff1a; https://meet.adminjs.net 在他的详情中有详细的使用…...

音频编辑软件:Studio One 6 中文

Studio One 6是一款功能强大的数字音乐制作软件&#xff0c;为用户提供一站式音乐制作解决方案。它具有直观的界面和强大的音频录制、编辑、混音和制作功能&#xff0c;支持虚拟乐器、效果器和第三方插件&#xff0c;可帮助用户实现高质量的音乐创作和制作。同时&#xff0c;St…...

MySQL语句|使用UNION和UNION ALL合并两个或多个 SELECT 语句的结果集

文章目录 举个通用的例子举个实际的例子 在MySQL中&#xff0c; UNION 和 UNION ALL 是用于合并两个或多个 SELECT 语句的结果集的操作符。 UNION 会去除结果集中的重复行&#xff0c;返回唯一的行&#xff0c;而 UNION ALL 会返回所有的行&#xff0c;包括重复行。 举个通…...

UNRAID 优盘制作

使用方法和开心方法&#xff1a; 如果重启之后显示器有信号但是黑屏无法正常引导系统&#xff0c;此为九代以后主板快速开机&#xff08;快速引导&#xff09;UNRAID并不支持快速引导所以会直接卡黑屏。所以发现这种情况的时候请进BIOS关闭和开机快速引导或和快有关系的任何开…...

二、Java中SpringBoot组件集成接入【MySQL和MybatisPlus】

二、Java中SpringBoot组件集成接入【MySQL和MybatisPlus】 1.MySQL和MybatisPlus简介2.maven依赖3.配置1.在application.yaml配置中加入mysql配置2.新增Mybatis-Plus配置类 4.参考文章 1.MySQL和MybatisPlus简介 MySQL是一种开源的关系型数据库管理系统&#xff0c;被广泛应用…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...