combineLatest
、merge
和 zip
是三个常用的操作符,用于组合和处理流式数据。以下是它们的区别以及在 Combine 中的使用场景
combineLatest
操作符,用于将多个发布者的最新元素进行组合
当任何一个发布者发出新元素时,combineLatest
会将所有发布者的最新元素组合成一个元组,并将该元组发送给订阅者。
let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<String, Never>()
let cancellable = publisher1
.combineLatest(publisher2)
.sink { (value1, value2) in
print("Combined: \(value1), \(value2)")
}
publisher1.send(1)
publisher2.send("A") // 输出 "Combined: 1, A"
publisher1.send(2) // 输出 "Combined: 2, A"
publisher2.send("B") // 输出 "Combined: 2, B"
应用场景:
当你希望在多个输入源中的任意一个发生变化时,更新界面或执行某些操作时,combineLatest 是一个有用的操作符。
merge
操作符,用于合并多个发布者的元素,无论它们来自哪个发布者,接收者都会按照它们的发出顺序进行接收
let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<Int, Never>()
let cancellable = publisher1
.merge(with: publisher2)
// .merge(with: pub2, pub3,
// pub4, pub5, pub6,
// pub7, pub8)
// 最多可以merge8个
.sink { value in
print("Merged: \(value)")
}
publisher1.send(1) // 输出 "Merged: 1"
publisher2.send(2) // 输出 "Merged: 2"
publisher1.send(3) // 输出 "Merged: 3"
publisher2.send(4) // 输出 "Merged: 4"
应用场景:
当你有多个来源的数据流,想要按照它们发生的顺序进行处理时,使用 merge 是一个常见的选择
zip
操作符,用于将多个发布者的元素按顺序进行配对,形成元组
只有当所有发布者都发出了新元素时,zip
才会将这些元素组合成一个元组发送给订阅者
let publisher1 = PassthroughSubject<Int, Never>()
let publisher2 = PassthroughSubject<String, Never>()
_ = publisher1
.zip(publisher2)
.sink(receiveCompletion: { completion in
print("结束了")
switch completion {
case .finished:
print("完成")
case .failure(let error):
print("错误:\(error.localizedDescription)")
}
}, receiveValue: { someValue in
print("value: \(someValue)")
})
publisher1.send(1)
publisher1.send(2)
publisher1.send(3)
publisher2.send("4") // value: (1, "4")
publisher2.send("5") // value: (2, "5")
// 有兴趣的朋友可以去试试send(completion: .finished)的情况
// publisher1.send(completion: .finished)
当我想zip多个publisher可以试试下面的方法,最多可以zip4个publisher
let pub1 = PassthroughSubject<Int, Never>()
let pub2 = PassthroughSubject<String, Never>()
let pub3 = PassthroughSubject<String, Never>()
let pub4 = PassthroughSubject<String, Never>()
let cancellable = Publishers.Zip4(pub1, pub2, pub3, pub4)
.sink { (value1, value2, value3, value4) in
print("Zipped: \(value1), \(value2), \(value3), \(value4)")
}
pub1.send(1)
pub1.send(2)
pub2.send("4")
pub3.send("5")
pub4.send("A") // Zipped: 1, 4, 5, A
应用场景:
当你想要确保所有的发布者都发出值,并在它们发出值时进行一些操作时,zip 是一个有用的操作符。例如,合并用户的用户名和密码进行认证