swift标准库中有append函数,可以在数组或字符串后添加一个相同类型的数据,比如

var str = "Hello"
str.append(" world!")
// Output
Hello world!

在Combi个ine中,也可以使用append来给Publisher在后面增加一个Output,或者增加一个Publisher,同时,Combine还提供了一个prepend操作符,和append相反,他是在前面增加一个Output,或是publisher

prepend Output

比如我们在playground中实现如下代码

// Combine
var subscriptions = Set<AnyCancellable>()// prepend 一个Output
func prependOutputExample() {let stringPublisher = ["World!"].publisherstringPublisher.prepend("Hello").sink(receiveValue: { print($0) }).store(in: &subscriptions)
}prependOutputExample()// Output
Hello
World!

stringPublisher本身的Output是字符串“World!”,经过prepend操作符处理后,他变成了

[ "Hello", "World!"]

所以sink接收时,会接收到两次数据,分别是“Hello”和“World!”。

将上面代码改成append后,会变成在后面添加Hello,就不再用代码举例了。

prepend Publisher

// prepend 一个Publisher
func prependPublisherExample() {let subject = PassthroughSubject<String, Never>()let stringPublisher = ["Break things!"].publisherstringPublisher.prepend(subject).sink(receiveValue: { print($0) }).store(in: &subscriptions)subject.send("Run code")subject.send(completion: .finished)
}prependPublisherExample()// Output
Run code
Break things!

stringPublisher是一个字符串数组的publisher

subject是Output类型为String的publisher,也可以说是subject,因为subject也是实现了publisher协议的一个类型,他有一个特殊的方法是send,可以通过send来手动发布数据。

在stringPublisher被订阅前,用prepend将subject挂接在stringPublisher的前面,这时候publisher的类型变为了

Publishers.Concatenate<PassthroughSubject<String, Never>, Publishers.Sequence<[String], Never>>

Publishers.Concatenate的定义是

A publisher that emits all of one publisher’s elements before those from another publisher.

在来自另一个发布者的元素之前发布一个发布者的所有元素的发布者。

所以在之后的sink中,我们依次接收到了两个publisher的Output数据,也就是Run code和Break things!

append操作符也是同样,只不过位置和prepend相反,一个在前,一个在后。

实际应用

在实际应用中,可以用在"拼接两个网络请求"的场景,比如我们有两个需要获取的网络数据,分别来自

http://jsonplaceholder.typicode.com/posts/1

json内容为

{"userId": 1,"id": 1,"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit","body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

和 http://jsonplaceholder.typicode.com/posts/2

json内容为

{"userId": 1,"id": 2,"title": "qui est esse","body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}

我们需要同时处理两个请求的返回值时,可以使用prepend或append操作符

在playground下使用如下代码:

// 1
struct TestData: Codable {var userId: Intvar id: Intvar title: Stringvar body: Stringinit(userId: Int = 0, id: Int = 0, title: String = "", body: String = "") {self.userId = userIdself.id = idself.title = titleself.body = body}
}// 2
let url1 = URL(string: "http://jsonplaceholder.typicode.com/posts/1")!
let url2 = URL(string: "http://jsonplaceholder.typicode.com/posts/2")!// 3
func getData1() -> AnyPublisher<TestData, Never> {return URLSession.shared.dataTaskPublisher(for: url1).map { $0.data }.decode(type: TestData.self, decoder: JSONDecoder()).replaceError(with: TestData()).eraseToAnyPublisher()
}// 4
func getData2() -> AnyPublisher<TestData, Never> {return URLSession.shared.dataTaskPublisher(for: url2).map { $0.data }.decode(type: TestData.self, decoder: JSONDecoder()).replaceError(with: TestData()).eraseToAnyPublisher()
}// 5
func sinkData() {let pub = getData1()pub.append(getData2())//.prepend(getData2()).sink { print("sinkData: \($0)") }.store(in: &subscriptions)
}sinkData()

1、创建JSON返回的数据结构

2、创建两个请求的URL

3、创建获取第一个数据请求的publisher(函数返回值)

4、创建获取第二个数据请求的publisher(函数返回值)

5、同时处理两个数据请求,使用append(getData2())时,打印结果是

sinkData: TestData(userId: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto")

sinkData: TestData(userId: 1, id: 2, title: "qui est esse", body: "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla")

可以看出来是先处理了第一个数据请求,再处理第二个数据请求,因为append是在后面添加。

注释掉append行,将prepend行取消注释,打印结果为

sinkData: TestData(userId: 1, id: 2, title: "qui est esse", body: "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla")

sinkData: TestData(userId: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto")

先处理了第二个数据请求,再处理第一个数据请求,因为prepend是在前面添加。

有一点要注意,prepend和append,要求被挂接的Output或publisher,与原publisher的Output类型要相同。对于我们最后一个网络请求的例子,因为两个请求返回的json数据格式是一样的,所以可以用prepend或append来实现。如果json数据格式不一样,并且还需要同时处理的话,则需要使用zip、merge或是combineLeast来实现。

Combine操作符append和prepend相关推荐

  1. jQuery中append()、prepend()与after()、before()的区别

    原文地址:https://www.cnblogs.com/afei-qwerty/p/6682963.html 在jQuery中,添加元素有append().prepend()和 after().be ...

  2. jquery中select操作append、prepend、remove、find、val、get、selectedIndex、attr、option

    全栈工程师开发手册 (作者:栾鹏) jquery系列教程2-DOM操作全解 jquery中select操作 jquery中select操作函数和字段包括append.prepend.remove.fi ...

  3. jquery创建添加append、prepend、appendTo、prependTo、after、insertAfter、before、insertBefore

    全栈工程师开发手册 (作者:栾鹏) jquery系列教程2-DOM操作全解 jquery创建添加元素 jquery支持直接使用h5代码作为参数创建元素,将元素添加到dom树中append.prepen ...

  4. jquery中append、prepend, before和after方法的区别

    1. append()和prepend() 假设 <div class='a'> //<---you want div c to append in this<div clas ...

  5. JavaScript 中 append()、prepend()、after()、before() 的区别

    内容 append().prepend().after().before() 的区别 jQuery 操作 DOM 之添加节点 方法名 作用 $(selector).append() 指定元素内部添加, ...

  6. JS DOM 编程复习笔记 -- insertBefore、insertAfter、append、prepend(七)

    今天我们来继续来复习DOM的一些插入方法,insertBefore(),append()和prepend()方法.前面我们只用到过一个appendChild()方法.我们一个个看语法和示例,包你看完就 ...

  7. jQuery中append、prepend等的用法与记忆

    jQuery中,有append.prepend等方法,容易搞混淆,在这里记录一下,以便于区分 大致有如下方法,可以理解为: append:后置x(-后面添加) prepend:前置x (-前面添加) ...

  8. 2021-12-23 睡前故事--jQuery-添加元素之append、prepend、after、before的区别

    jQuery-添加元素之append.prepend.after.before的区别 小萝卜儿灵魂画师

  9. appendChild append insertBefore prepend

    CreateTime--2017年11月2日16:57:59 Author:Marydon appendChild()与append() insertBefore()与prepend()区别与联系 描 ...

最新文章

  1. 反弹木马——本质上就是一个开80端口的CS程序,伪造自己在浏览网页
  2. ios 缺少合规证明
  3. 【安全漏洞】从补丁追溯漏洞触发路径
  4. html head
  5. mysql语法6_全面接触SQL语法(6)_mysql
  6. 牛客题霸 [矩阵元素查找] C++题解/答案
  7. /lib/libcrypto.so“ not found,is 32-bit instead of 64-bit
  8. 不要放弃,你的梦想是这个世界上最伟大的事情。
  9. 在指定路径或者是文件名查找指定的字符串
  10. 上岸 | 青椒博士毕业后未返校任教,被判返还高校41万余元
  11. SE Springer小组之《Spring音乐播放器》可行性研究报告五、六
  12. 知识点速记 | 本机号码一键登录?
  13. 极光开发者周刊【No.0827】
  14. IDEACPU占用100%_卡顿 解决办法
  15. android 遍历短信,Android通过for循环批量发送短信
  16. 查找bug的方法(随笔)
  17. 《The Tobii I-VT Fixation Filter Algorithm description》阅读
  18. 实际场景中的多线程使用
  19. Nginx的下载与安装及配置
  20. 电压跟随器的作用-摘录+自解

热门文章

  1. java学习笔记<二>——OJ习题练习(15-21)
  2. OpenCV双边滤波bilateralFilter去除脸部雀斑
  3. 保姆级手把手教学 数学建模美赛信件格式latex模板(overleaf)
  4. Charles SSL黑白名单
  5. Drools 规则引擎
  6. Android学习羁绊之网络技术
  7. 如何搭建直播平台?低延时连麦+人工智能让互动升级
  8. go error接口与errors包详解
  9. 阿里云配置SSL证书
  10. 从航海贸易到元宇宙,从公司制到DAO