转换和组合流
使用 flatMap、merge、combineLatest 和 zip。
转换和组合流 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
处理数据流
在组合框架中,publisher 会随时间发出一系列值。真正强大的地方在于运算符,它们可以将这些数据流转换并组合成新的数据流。
本课将介绍最重要的转换和组合运算符:flatMap、merge、combineLatest 和 zip。
map 与 flatMap
map 将每个值转换为另一个值。flatMap 更进一步——它将每个值转换为一个新的 publisher,再将结果扁平化为单一数据流。
当每个输入都应触发另一个异步操作时,请使用 flatMap。
flatMap 实战
这里将用户标识符数据流映射为网络请求数据流,再将其扁平化为一个用户数据流。
userIdPublisher
.flatMap { id in
apiClient.fetchUser(id: id)
}
.sink { user in
print("Loaded", user.name)
}
.store(in: &cancellables)控制 flatMap 并发
默认情况下,flatMap 会立即订阅所有内部 publisher。您可以使用 maxPublishers 限制并发量,避免向服务器发送过多请求。
idsPublisher
.flatMap(maxPublishers: .max(2)) { id in
apiClient.fetchUser(id: id)
}
.sink { print($0) }
.store(in: &cancellables)merge
merge 会将多个相同类型的 publisher 中的值交错合并到一个数据流中,并在每个值到达后立即发出。
let combined = buttonTapA
.merge(with: buttonTapB)
combined
.sink { print("A tap from either button") }
.store(in: &cancellables)combineLatest
combineLatest 会在任意一个输入 publisher 发出值时触发,并将每个 publisher 的最新值配对在一起。它非常适合表单验证,因为表单验证必须同时考虑多个字段。
usernamePublisher
.combineLatest(passwordPublisher)
.map { name, pass in
!name.isEmpty && pass.count >= 8
}
.sink { isValid in
print("Form valid:", isValid)
}
.store(in: &cancellables)combineLatest 的行为
请注意:在每个输入都至少产生过一个值之前,combineLatest 不会发出任何内容。此后,任意输入每次发出新值时,都会将它与其他输入的最新值组合后输出。
zip
zip 会按照索引配对值:将 A 的第一个值与 B 的第一个值配对,第二个与第二个配对,以此类推。它会等待两侧在每个位置都有值。
let names = ["Ann", "Bob", "Cy"].publisher
let ages = [30, 25, 41].publisher
names
.zip(ages)
.sink { name, age in
print(name, "is", age)
}
.store(in: &cancellables)combineLatest 与 zip
这两个运算符很容易混淆:
- combineLatest——任意值发出时触发,使用每个输入的最新值
- zip——仅在索引对应的值配对时触发
实时状态请使用 combineLatest;要将并行结果一一对齐,请使用 zip。
为并行工作进行组合
当您并行运行相互独立的请求并等待它们全部完成时,zip 非常有用。
fetchProfile
.zip(fetchSettings)
.sink { profile, settings in
print("Both loaded")
}
.store(in: &cancellables)串联运算符
实际的流水线会将多个运算符串联起来,以声明式地表达复杂的异步流程。
searchTextPublisher
.removeDuplicates()
.flatMap { query in
apiClient.search(query)
}
.map { results in
results.prefix(10)
}
.sink { print($0) }
.store(in: &cancellables)快速检查
测试您对运算符的理解。
回顾
您学习了如何转换和组合数据流:
- flatMap——将值转换为 publisher 并扁平化
- merge——交错合并相同类型的数据流
- combineLatest——使用各输入的最新值,在任意输入发出值时触发
- zip——按照索引配对
这些运算符可以让您以声明式方式组合复杂的异步逻辑。
常见问题解答
「转换和组合流」课时是免费的吗?
是的 — 「转换和组合流」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「转换和组合流」这节课中我会学到什么?
使用 flatMap、merge、combineLatest 和 zip。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「转换和组合流」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 转换和组合流
- 调度器与线程
- 错误处理运算符
- 自定义发布者与订阅者