Swift Combine 管道 从入门到精通三
Combine 系列
- Swift Combine 从入门到精通一
- Swift Combine 发布者订阅者操作者 从入门到精通二
1. 用弹珠图描述管道
函数响应式编程的管道可能难以理解。 发布者生成和发送数据,操作符对该数据做出响应并有可能更改它,订阅者请求并接收这些数据。 这本身就很复杂,但 Combine 的一些操作符还可能改变事件发生的时序 —— 引入延迟、将多个值合并成一个值等等。 由于这些比较复杂可能难以理解,因此函数响应式编程社区使用一种称为 弹珠图 的视觉描述来说明这些变化。
在探索 Combine 背后的概念时,你可能会发现自己正在查看其他函数响应式编程系统,如 RxSwift 或 ReactiveExtensions。 与这些系统相关的文档通常使用弹珠图。
弹珠图侧重于描述特定的管道如何更改数据流。 它显示数据是如何随着时间的变化而变化的,以及这些变化的时序。

怎么看懂弹珠图:
- 不管周围描述的是什么元素,在该例子的图上,中心是一个操作符。 具体的操作符的名称通常位于中心块上。
- 上面和下面的线表示随着时间移动的数据, 由左到右。 线上的符号表示离散着的数据。
- 我们通常假定数据正在向下流动。 在这种情况下,顶线表示对操作符的输入,底线表示输出。
- 在某些图表中,顶线上的符号可能与底线上的符号不同, 这时图表通常意味着输出的类型与输入的类型不同。
- 在有些图中,你也可能在时间线上看到竖线 “|” 或 “ X ” 或终结时间线, 这用于表示数据流的结束。 时间线末端的竖线意味着数据流已正常终止。 “X” 表示抛出了错误或异常。
这些图表有意忽略管道的配置,而倾向于关注一个元素来描述该元素的工作原理。
2. 用弹珠图描述 Combine
这本书对基本的弹珠图做了扩展并稍作修改,用来突出 Combine 的一些细节。 最显著的区别是输入和输出是两条线。 由于 Combine 明确了输入和失败类型,因此它们在图表中也被分开来单独表示。

发布者的输出和失败类型,用上面的两条线来表示,然后数据经过操作符之后会流向下方。 操作符同时作为订阅者和发布者,处在中间, 订阅者接收的数据和失败类型,用下面的两条线来表示。
为了说明这些图表与代码的关系,让我们来看一个简单的示例。 在这个例子中,我们将关注 map 操作符以及如何用此图表描述它。
let _ = Just(5).map { value -> String in switch value {case _ where value < 1:return "none"case _ where value == 1:return "one"case _ where value == 2:return "couple"case _ where value == 3:return "few"case _ where value > 8:return "many"default:return "some"}}.sink { receivedValue inprint("The end result was \(receivedValue)")}
- 提供给 “
.map()” 函数的闭包接收一个<Int>类型的值,并将其转换为<String>类型。 由于失败类型<Never>没有改变,因此直接输出它。
以下图表表示了此代码片段。 此图描述了更详细的内容:它在图表中展示了闭包中的代码,以显示其关联性。

许多 Combine 的操作符都由你用一个闭包来配置。 大多数图表都不会将它包含在其中。 这意味着你通过 Combine 中的闭包提供的任何代码都将被简化成一个框,而不是详细的描述它。
此 map 操作符的输入类型为 <Int>,在最上面的线上用通用的语法进行表示。 传递给该操作符的失败类型为 <Never>,在输入类型的正下方用同一语法中表示。
map 操作符没有更改或影响失败类型,只是将其进行了传递。 为了表示这一点,上面输入和下面输出的失败类型都用虚线来表示,以弱化它。
最上面的线上展示了单一输入值(5), 在这个例子中,它在线上的具体位置是没有意义的,仅表示它是单一值。 如果线上有多个值,则左侧的值将优于在右侧的任意值被发送给 map 操作符。
当值到达操作符时,值 5 作为变量的 值 传递给闭包。 这个例子中,闭包的返回类型(本例中为 <String> )定义了当闭包中的代码完成并返回其值时 map 操作符的输出类型。 在这个例子中,输入了 5 然后返回了字符串 some。 字符串 some 展示在输入值正下方的输出线上,这意味着没有明显的延迟。
3. Back pressure
Combine 的设计使订阅者控制数据流,因此它也控制着在管道中处理数据的内容和时间。 这是一个在 Combine 中被叫做 back-pressure 的特性。
这意味着由订阅者通过提供其想要或能够接受多少信息量来推动管道内数据的处理。 当订阅者连接到发布者时,它会基于特定的 需求 去请求数据。
特定需求的请求通过组成管道进行传递。 每个操作符依次接受数据请求,然后请求与之相连的发布者提供信息。
在 Combine 框架的第一个版本中( iOS 13.3 和 macOS 10.15.2 之前),当订阅者请求具有特定需求的数据时,该请求是异步发生的。 由于此过程中是充当触发器的订阅者,去触发其连接的操作符,并最终触发发布者去请求数据,因此这意味着在某些情况下存在数据丢失的可能性。 因此,在 iOS 13.3 和以后的 Combine 版本中,请求的过程被改成了同步/阻塞线程的。 实际上,这意味着在发布者收到发送数据的请求之前,你可以更确信后序的管道已经完全准备好处理接下来的数据了。
有了订阅者驱动数据流这个特性,它允许 Combine 去取消这个过程。 订阅者均遵循 Cancellable 协议。 这意味着它们都有一个 cancel() 函数,可以调用该函数来终止管道并停止所有相关处理。
当管道被取消时,管道是不期望被重新启动的。 相比于重启一个被取消的管道,开发者更应该去创建一个新的管道。
参考
https://heckj.github.io/swiftui-notes/index_zh-CN.html
代码
https://github.com/heckj/swiftui-notes
相关文章:
Swift Combine 管道 从入门到精通三
Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二 1. 用弹珠图描述管道 函数响应式编程的管道可能难以理解。 发布者生成和发送数据,操作符对该数据做出响应并有可能更改它,订阅者请求并接收这些数据。 这…...
【RISC-V DSP设计】基于CEVA DSP架构的指令集分析(二)-函数列表
目录 表3-1:定点滤波器功能 表3-2:定点快速傅里叶变换(FFT)函数 表3-3:定点数学函数 表3-4:定点三角函数 表3-5:定点向量函数 表3-6:定点矩阵函数 表3-7:浮点滤波…...
蓝桥杯(Web大学组)2022国赛真题:水果消消乐
思路: 记录点击次数,点击次数为1时,记录点击下标(用于隐藏or消除)、点击种类,点击次数为2时,判断该下标所对应种类与第一次是否相同 相同:两个都visibility:hidden (占…...
LeetCode--代码详解 155.最小栈
155.最小栈 题目 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶…...
第6讲后端鉴权拦截器实现
后端鉴权拦截器实现 package com.java1234.interceptor;import com.java1234.util.JwtUtils; import com.java1234.util.StringUtil; import io.jsonwebtoken.Claims; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerI…...
uniapp从入门到进阶
一、了解uniapp 跨平台开发:Uniapp可以同时开发多个平台的应用,只需编写一套代码即可。开发者可以通过编写Vue组件来构建界面,通过编写JavaScript代码来实现业务逻辑。 页面和组件:Uniapp的页面和组件都是基于Vue组件的ÿ…...
CDN缓存404、403状态码
可以参考一下:浏览器缓存和 CDN 在前端的落地 事故记录: 前端发版时存在新旧两个容器,在资源替换的间隙,用户请求到的肯定是新容器的html文件,但是根据新容器的html向新静态资源发起请求,此时旧容器还没有…...
【Python网络编程之DHCP服务器】
🚀 作者 :“码上有前” 🚀 文章简介 :Python开发技术 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 Python网络编程之DHCP服务器 代码见资源,效果图如下一、实验要求二、协议原理2.1 D…...
【MySQL】:深入理解并掌握DML和DCL
🎥 屿小夏 : 个人主页 🔥个人专栏 : MySQL从入门到进阶 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一. DML1.1 添加数据1.2 修改数据1.3 删除数据 二. DCL2.1 管理用户2.2 权限控制…...
CSP-动态规划-最长公共子序列(LCS)
一、动态规划 动态规划(Dynamic Programming,简称DP)主要用于求解可以被分解为相似子问题的复杂问题,特别是在优化问题上表现出色,如最短路径、最大子数组和、编辑距离等。动态规划的核心思想是将原问题分解为较小的子…...
安装nodejs2011并配置npm仓库
1. 安装nodejs 选择2011版本下载 在安装目录(个人情况)下 D:\Program Files\nodejs2011创建2个文件夹: node_global (依赖库) node_cache (缓存) 然后在当前目录下cmd进入dos窗口,执行: npm c…...
排序C++代码(已更:快速排序,归并排序)
一、快速排序 #include<iostream> using namespace std;//设定三个数组,判断排序算法代码的正确性 int a[100]{3,4,2,6,9,7,1,0,1,2,3,3,5,6,7,8,3,4,5}; int b[100]{1,5,3,4}; int c[100]{7,8,9,1,2,3};void quickSort(int* num,int l,int r){if(l>r) re…...
CentOS 7.9安装Tesla M4驱动、CUDA和cuDNN
正文共:1333 字 21 图,预估阅读时间:2 分钟 上次我们在Windows上尝试用Tesla M4配置深度学习环境(TensorFlow识别GPU难道就这么难吗?还是我的GPU有问题?),但是失败了。考虑到Windows…...
Java设计模式——策略
前言 策略模式是平时Java开发中常用的一种,虽然已有很多讲解设计模式的文章,但是这里还是写篇文章来从自己理解的角度讲解一下。 使用场景 我们不妨进行场景假设,要对我们的软件进行授权管理:在启动我们的软件之前先要校验是否…...
线性代数的本质 1 向量
向量是线性代数中最为基础的概念。 何为向量? 从物理上看, 向量就是既有大小又有方向的量,只要这两者一定,就可以在空间中随便移动。 从计算机应用的角度看,向量和列表很接近,可以用来描述某对象的几个不同…...
基于JAVA的贫困地区人口信息管理系统 开源项目
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 人口信息管理模块2.2 精准扶贫管理模块2.3 特殊群体管理模块2.4 案件信息管理模块2.5 物资补助模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 人口表3.2.2 扶贫表3.2.3 特殊群体表3.2.4 案件表3.2.5 物资补助表 四…...
【后端高频面试题--Mybatis篇】
🚀 作者 :“码上有前” 🚀 文章简介 :后端高频面试题 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 后端高频面试题--Mybatis篇 什么是Mybatis?Mybatis的优缺点?Mybatis的特点…...
【笔记】Helm-5 Chart模板指南-12 .helmignore文件
.helmignore文件 .helmignore文件用来指定您不想包含在您的helm chart中的文件。 如果该文件存在,helm package命令会在打包应用时忽略所有在.helmignore文件中匹配的文件。 有助于避免不需要的或敏感文件及目录添加到您的helm chart中。 .helmignore文件支持Uni…...
【MySQL】表的增删改查(基础)
MySQL表的增删改查(基础) 1. CRUD2. 新增(Create)2.1 单行数据全列插入2.2 多行数据 指定列插入 3. 查询(Retrieve)3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重:DISTINCT…...
Android矩阵Matrix动画缩放Bitmap移动手指触点到ImageView中心位置,Kotlin
Android矩阵Matrix动画缩放Bitmap移动手指触点到ImageView中心位置,Kotlin 借鉴 Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)-CSDN博客 在此基础上实现手指在屏幕上点击后&…...
ESP32-C3深度睡眠唤醒踩坑记:GPIO0~5始终低电平?手把手教你用Arduino框架正确配置RTC GPIO
ESP32-C3深度睡眠唤醒实战指南:破解GPIO0~5低电平陷阱 凌晨三点的调试灯依然亮着,这是我本周第三次被ESP32-C3的深度睡眠唤醒问题折磨到深夜。作为一款主打低功耗的物联网芯片,ESP32-C3的深度睡眠模式本该是电池供电设备的福音,但…...
从Overleaf回归本地:为什么我最终选择了Windows下的MiKTeX和VS Code组合?
从Overleaf回归本地:为什么我最终选择了Windows下的MiKTeX和VS Code组合? 作为一名长期依赖Overleaf的科研工作者,我曾在云端LaTeX编辑器的便利性中如鱼得水——直到开始撰写我的博士学位论文。当文档规模超过200页、包含数百个交叉引用和复杂…...
Perplexity实战技能树全拆解:从零到精通的5级进阶路径及每日训练清单
更多请点击: https://kaifayun.com 第一章:Perplexity核心原理与平台生态概览 Perplexity 是一种基于语言模型困惑度(perplexity)评估范式的智能问答与研究协作平台,其核心并非单纯依赖大模型生成能力,而是…...
自适应滤波器提取胎儿心电信号的MATLAB及FPGA实现
自适应滤波器提取胎儿心电信号的MATLAB及FPGA实现 【下载地址】自适应滤波器提取胎儿心电信号的MATLAB及FPGA实现 本项目提供了一个完整的工程代码,用于实现自适应滤波器提取胎儿心电信号的MATLAB及FPGA实现。自适应滤波器是一种能够根据环境变化自动调整滤波器参数…...
Auto Edit 日常迭代踩坑实录:OpenAI Codex CLI 三种权限模式配置差异与 2 类高频报错修复
1. Auto Edit 模式不是“全自动”,而是最易失控的权限模式 大多数人第一次在项目里启用 codex cli --mode=auto-edit,是冲着“自动改代码”去的。我也是。直到某天凌晨两点,CI 流水线突然报出 17 个 test failure,而 git diff 显示——它把一个 if (user.role === admin) …...
35+ 程序员必读:收藏!AI时代如何逆袭,成为最抢手的技术人才?
AI时代对程序员的影响是深远的,尤其是对于35岁的程序员,面临着被淘汰的压力。然而,AI也可以成为他们的优势,通过利用AI工具,他们可以放大自己的长板,如架构经验、业务理解和工程判断力。文章建议35岁的程序…...
知识库搭建:从认知到实践的完整指南
知识库搭建:从认知到实践的完整指南一、先搞清楚:什么是知识? 数据 → 信息 → 知识 → 智慧 是经典的 DIKW 金字塔,描述了认知逐层升维的过程:层级核心定义关键特征回答的问题示例数据原始事实,raw facts离…...
任天堂Switch游戏备份终极指南:nxdumptool完全解析
任天堂Switch游戏备份终极指南:nxdumptool完全解析 【免费下载链接】nxdumptool Generates XCI/NSP/HFS0/ExeFS/RomFS/Certificate/Ticket dumps from Nintendo Switch gamecards and installed SD/eMMC titles. 项目地址: https://gitcode.com/gh_mirrors/nx/nxd…...
Perplexity认证备考资源严重稀缺!仅开放3个月的模拟题库已限流,速领2024Q3最新版PDF+视频解析
更多请点击: https://codechina.net 第一章:Perplexity认证考试概览与最新动态 Perplexity认证考试是由Perplexity AI官方推出的面向开发者、AI工程师及技术决策者的专业能力评估体系,旨在验证考生在大语言模型原理、提示工程实践、API集成、…...
C语言数组内存布局解析:从连续存储到性能优化实践
1. 项目概述:从内存视角重新认识C语言数组很多C语言初学者,包括一些已经工作一两年的朋友,对数组的理解可能还停留在“一组连续的同类型变量”这个层面。这没错,但如果你只看到这一层,写代码时就容易踩坑,尤…...
