【RxJava】map过程中各个Observable生命周期分析
map和flatMap的区别
首先说下map和flatMap的区别,防止有对RxJava还不够熟悉的小伙伴
- map的Function指定如何将A转为B
- flatMap的Function则指定如何将Observable<A>转为Observable<B>
- map和flatMap最终的转换结果都是Observable<B>
- flatMap由于可以自己创建Observable,因此更为强大灵活,map比较简单
Observable生命周期测试
下面,我们创建一个Observable,并通过map和flatMap进行多次Observable转换
分别在正常流程和异常流程下,测试map过程中各个Observable的生命周期执行流程
import io.reactivex.rxjava3.core.Observable;@SuppressWarnings("all")public class RxJavaMapTest {public static class Action {public static String A() {System.out.println("A Execute");return "A";}public static Observable<String> B() {System.out.println("B Execute");return Observable.just("B");}public static Observable<String> C() {System.out.println("C Execute");//throw new RuntimeException("Error");return Observable.just("C");}public static Observable<String> D() {System.out.println("D Execute");return Observable.just("D");}public static Observable<String> E() {System.out.println("E Execute");return Observable.just("E");}}public static void main(String[] args) {Observable.just("").map(o -> Action.A()).doOnSubscribe(aAction -> {System.out.println("doOnSubscribe A");}).doOnNext(o -> {System.out.println("doOnNext A1");}).doOnNext(o -> {System.out.println("doOnNext A2");}).doOnError(e -> {System.out.println("doOnError A");}).doOnComplete(() -> {System.out.println("doOnComplete A");}).doFinally(() -> {System.out.println("doOnFinally A");}).flatMap(o -> Action.B()).doOnSubscribe(aAction -> {System.out.println("doOnSubscribe B");}).doOnNext(o -> {System.out.println("doOnNext B");}).doOnError(e -> {System.out.println("doOnError B");}).doOnComplete(() -> {System.out.println("doOnComplete B");}).doFinally(() -> {System.out.println("doOnFinally B");}).flatMap(o -> Action.C()).doOnSubscribe(o -> {System.out.println("doOnSubscribe C");}).doOnNext(o -> {System.out.println("doOnNext C");}).doOnError(e -> {System.out.println("doOnError C");}).doOnComplete(() -> {System.out.println("doOnComplete C");}).doFinally(() -> {System.out.println("doOnFinally C");}).flatMap(o -> Action.D()).doOnSubscribe(o -> {System.out.println("doOnSubscribe D");}).doOnNext(o -> {System.out.println("doOnNext D");}).doOnError(e -> {System.out.println("doOnError D");}).doOnComplete(() -> {System.out.println("doOnComplete D");}).doFinally(() -> {System.out.println("doOnFinally D");}).flatMap(o -> Action.E()).doOnSubscribe(o -> {System.out.println("doOnSubscribe E");}).doOnNext(o -> {System.out.println("doOnNext E");}).doOnError(e -> {System.out.println("doOnError E");}).doOnComplete(() -> {System.out.println("doOnComplete E");}).doFinally(() -> {System.out.println("doOnFinally E");}).subscribe(o -> System.out.println("doOnFinally X"),e -> System.out.println("doOnError X"),() -> System.out.println("doOnFinally X"));System.out.println("Task Finish");}}
正常情况下的运行结果
doOnSubscribe A
doOnSubscribe B
doOnSubscribe C
doOnSubscribe D
doOnSubscribe E
A Execute
doOnNext A1
doOnNext A2
B Execute
doOnNext B
C Execute
doOnNext C
D Execute
doOnNext D
E Execute
doOnNext E
doOnFinally X
doOnComplete A
doOnComplete B
doOnComplete C
doOnComplete D
doOnComplete E
doOnFinally X
doOnFinally E
doOnFinally D
doOnFinally C
doOnFinally B
doOnFinally A
Task Finish
C发生异常时的运行结果
doOnSubscribe A
doOnSubscribe B
doOnSubscribe C
doOnSubscribe D
doOnSubscribe E
A Execute
doOnNext A1
doOnNext A2
B Execute
doOnNext B
C Execute
doOnFinally A
doOnFinally B
doOnError C
doOnFinally C
doOnError D
doOnFinally D
doOnError E
doOnError X
doOnFinally E
Task Finish
下面,我们基于以上两次运行结果进行分析
如果有其它更深层次的疑问,可以复制以上代码,自己调整继续运行
正常流程下的生命周期流程
- ABCDEX依次执行onSubscribe
- ABCDE依次执行Function和onNext
- ABCDEX依次执行onComplete
- XEDCBD依次执行onFinally
C发生异常时的生命周期流程
- ABCDE依次执行onSubscribe
- AB依次执行Function和onNext
- C执行Function,但触发Error
- AB不再执行onComplete,依次执行onFinally
- C执行onError和onFinally
- D执行onError和onFinally
- E执行onError
- X执行onError
- E执行onFinally
流程分析
- 执行subscribe方法之后,B订阅A,C订阅B。。。
- 无异常时,onFinally是按EDCBD顺序执行的,说明Subscriber工作全部完成后,Observable才会执行onFinally
- C触发Error后,AB都不执行onComplete,说明Subscriber处理时发生错误,Observable也会被视为工作未完成
- C触发Error后,AB立刻执行onFinally,说明Subscriber发生异常时,Observable工作直接结束
- C触发Error后,AB不执行onError,但DE会执行onError,说明Observable错误,会引发Subscriber错误
多次map过程中,异常处理方式可以总结为
- 发生异常时,所有的OnSubscribe都会执行
- 发生异常时,所有的OnFinally都会执行
- 发生异常时,所有的OnComplete都不会执行
- 发生异常时,后续的OnError都会执行
- 发生异常时,后续的OnNext都不会执行
- 发生异常时,后续的Function都不会执行
多次map过程中,Function的处理方式
- 多次map实际上是依次订阅的关系,B订阅A,再将自己的结果发射给C
- map方法只是创建了一个起到包装作用的Observable,将所有回调对象,和用于转换的Function保存了起来
- Function并不会立即执行,而是等subscribe之后,等到上个Observable处理成功,才会执行
subscribe回调和doOn系列回调的区别
- 效果一样,只是给Observable提供了不同的回调设置方式
- subscribe回调是设置给最后一个Observable的,和前面代码没有任何关系,不要复杂化
- 一个Observable可以有多个回调,它们都会生效,并不会相互覆盖,按设置先后顺序执行
相关文章:
【RxJava】map过程中各个Observable生命周期分析
map和flatMap的区别 首先说下map和flatMap的区别,防止有对RxJava还不够熟悉的小伙伴 map的Function指定如何将A转为BflatMap的Function则指定如何将Observable<A>转为Observable<B>map和flatMap最终的转换结果都是Observable<B>flatMap由于可以…...

vue 获取上一周和获取下一周的日期时间
效果图: 代码 <template><div><div style"padding: 20px 0;"><div style"margin-left: 10px; border-left: 5px solid #0079fe; font-size: 22px; font-weight: 600; padding-left: 10px">工作计划</div><di…...
线性代数 第四章 线性方程组
一、矩阵形式 经过初等行变换化为阶梯形矩阵。当,有解;当,有非零解。 有解,等价于 可由线性表示 克拉默法则:非齐次线性方程组中,系数行列式,则方程组有唯一解,且唯一解为 其中是…...
@DateTimeFormat和@JsonFormat注解
在日常开发中,有用到时间类型作为查询参数或者查询结果有时间参数的一般都会见过这两个注解。 DateTimeFormat(pattern “yyyy-MM-dd HH:mm:ss”)注解用于解析请求接口入参。将入参的字符串按照pattern设置的格式来转换成日期时间对象。 JsonFormat(timezone “G…...

做抖音短视频会经历哪些阶段?
今天来聊聊那些在抖音做大的老板,从开始到后期经历的四个阶段,以及每个阶段的工作重心 1、0—1的阶段 0—1的起步阶段是整个阶段最有难度的一环,很多人对0到1的认知是有错误的,以为爆过几条视频就已经进阶了 想要实现0-1的突破…...

【Mquant】2、量化平台的选择
文章目录 一、选择因素二、常见的量化平台三、为什么选择VeighNa?四、参考 一、选择因素 功能和工具集:量化平台应该提供丰富的功能和工具集,包括数据分析、策略回测、实时交易等。不同的平台可能有不同的特点和优势,可以根据自己…...

iPhone手机如何恢复删除的视频?整理了3个好用方法!
在日常生活中,我们会把各种各样的视频存放在手机里。这些视频记录着我们生活中的点点滴滴,每一帧都承载着珍贵的记忆。但如果我们不小心将这些重要视频删除了该怎么办?如何恢复删除的视频?本文将以iPhone手机为例子,教…...

全网最全的RDMA拥塞控制入门基础教程
RDMA-CC(全网最全的RDMA拥塞控制入门基础教程) 文章目录 RDMA-CC(全网最全的RDMA拥塞控制入门基础教程)DMARDMARDMA举例RDMA优势RDMA的硬件实现方法RDMA基本术语FabricCA(Channel Adapter)Verbs 核心概念Me…...

分布式消息队列:RabbitMQ(1)
目录 一:中间件 二:分布式消息队列 2.1:是消息队列 2.1.1:消息队列的优势 2.1.1.1:异步处理化 2.1.1.2:削峰填谷 2.2:分布式消息队列 2.2.1:分布式消息队列的优势 2.2.1.1:数据的持久化 2.2.1.2:可扩展性 2.2.1.3:应用解耦 2.2.1.4:发送订阅 2.2.2:分布式消息队列…...
Redis集群脑裂
1. 概述 Redis 集群脑裂(Cluster Split Brain)是指在 Redis 集群中,由于网络分区或通信问题,导致集群中的节点无法相互通信,最终导致集群内部发生分裂,出现多个子集群,每个子集群认为自己是有效…...
GEE教程——随机样本点添加经纬度信息
简介: 有没有办法在绘制散点图后将样本的坐标信息(纬度/经度)添加到.CSV表格数据中? 这里我们很多时候我们需要加载样本点的基本信息作为属性,本教程主要的目的就是我们选取一个研究区,然后产生随机样本点,然后利用坐标函数,进行样本点的获取经纬度,然后通过循环注意…...
PyTorch入门学习(十):神经网络-非线性激活
目录 一、简介 二、常见的非线性激活函数 三、实现非线性激活函数 四、示例:应用非线性激活函数 一、简介 在神经网络中,激活函数的主要目的是引入非线性特性,从而使网络能够对非线性数据建模。如果只使用线性变换,那么整个神…...
《golang设计模式》第三部分·行为型模式-03-解释器模式(Interpreter)
文章目录 1. 概述1.1 角色1.2 类图1.3 优缺点 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 解释器模式(Interpreter)是用于表达语言语法树和封装语句解释(或运算)行为的对象。 1.1 角色 AbstractExpression(抽象表…...

Windows个性化颜色睡眠后经常改变
问题再现 我把系统颜色换成了一种红色,结果每次再打开电脑又变回去了(绿色); 原因是因为wallpaper engine在捣蛋 需要禁用修改windows配色这一块选项; 完事!原来是wallpaper engine的问题;...
calico ipam使用
calico ipam使用 前面的文章pod获取ip地址的过程中提到过calico使用的IP地址的管理模块是其自己开发的模块calico-ipam,本篇文章来讲述下其具体用法。 一、环境信息 版本信息 本环境使用版本是k8s 1.25.3 [rootnode1 ~]# kubectl get node NAME STATUS ROLES …...
Redis系统学习(高级篇)-Redis持久化-AOF方式
目录 一、是什么AOF? 二、AOF如何开启 以及触发策略有哪些 三、AOF文件重写 四、AOF与RDB对比 一、是什么AOF? 就是通过每次记录写操作,最终通过来依次这些命令来达到恢复数据的目的 二、AOF如何开启 以及触发策略有哪些 save "&q…...

云安全-云原生基于容器漏洞的逃逸自动化手法(CDK check)
0x00 docker逃逸的方法种类 1、不安全的配置: 容器危险挂载(挂载procfs,Scoket) 特权模式启动的提权(privileged) 2、docker容器自身的漏洞 3、linux系统内核漏洞 这里参考Twiki的云安全博客,下…...

精选10款Python可视化工具,请查收
今天我们会介绍一下10个适用于多个学科的Python数据可视化库,其中有名气很大的也有鲜为人知的。 1、matplotlib matplotlib 是Python可视化程序库的泰斗。经过十几年它仍然是Python使用者最常用的画图库。它的设计和在1980年代被设计的商业化程序语言MATLAB非常接近…...
大数据(21)-skew-GroupBy
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
window压缩包安装mongodb并注册系统服务
下载解压包 https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-5.0.22.zip启动mongod 解压压缩包 至 d:\mongodb目录中,创建目录data、logs。并创建配置文件mongod.conf输入以下配置 dbpath d:\mongodb\data logpath d:\mongodb\logs\mongo.log loga…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...