Combine操作符Mixing示例
5个月前 • 211次点击 • 来自 移动端
标签: Swift
Mixing 合并
Mixing指的是将多个publishers合并
combineLatest
将2个或多个publishers合并
示例1
let firstPublisher = PassthroughSubject<Int, Never>()
let secondPublisher = PassthroughSubject<String, Never>()
firstPublisher
.combineLatest(secondPublisher)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
firstPublisher.send(1)
secondPublisher.send("a")
firstPublisher.send(2)
输出:
(1, "a")
(2, "a")
注意,combineLatest会读取最新的数据或者数据序列,如果更改以上代码如下:
示例2
let firstPublisher = PassthroughSubject<Int, Never>()
let secondPublisher = PassthroughSubject<String, Never>()
firstPublisher
.combineLatest(secondPublisher)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
firstPublisher.send(1)
firstPublisher.send(2)
secondPublisher.send("a")
输出:
(2, "a")
问题,为甚不是输出
(1, "a")
(2, "a")
重点在于理解Latest
:
firstPublisher会等待secondPublisher最新的数据进行组合成元祖,上例中firstPublisher第一个消息(1)并没有等到secondPublisher的数据就被其他数据(2)覆盖,则不会产生配对输出
示例3
let firstPublisher = PassthroughSubject<Int, Never>()
let secondPublisher = PassthroughSubject<String, Never>()
firstPublisher
.combineLatest(secondPublisher)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
firstPublisher.send(1)
secondPublisher.send("a")
firstPublisher.send(2)
secondPublisher.send("b")
secondPublisher.send("c")
输出:
(1, "a")
(2, "a")
(2, "b")
(2, "c")
类似的函数还有CombineLatest3
,CombineLatest4
,用法如下:
let firstPublisher = PassthroughSubject<Int, Never>()
let secondPublisher = PassthroughSubject<String, Never>()
let threePublisher = PassthroughSubject<String, Never>()
Publishers
.CombineLatest3(firstPublisher, secondPublisher, threePublisher)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
firstPublisher.send(1)
secondPublisher.send("a")
threePublisher.send("b")
firstPublisher.send(2)
输出:
(1, "a", "b")
(2, "a", "b")
merge
merge只要接受到新数据就输出,适用于合并多个无序的publishers
let pub1 = PassthroughSubject<Int, Never>()
let pub2 = PassthroughSubject<Int, Never>()
let pub3 = PassthroughSubject<Int, Never>()
let pub4 = PassthroughSubject<Int, Never>()
let pub5 = PassthroughSubject<Int, Never>()
pub1
.merge(with: pub2, pub3, pub4, pub5)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
pub1.send(1)
pub2.send(2)
pub3.send(3)
pub4.send(4)
pub5.send(5)
pub1.send(1)
pub3.send(3)
pub5.send(5)
同样,可使用Publishers.MergeMany合并
zip
zip同combineLatest在结果上一样输出元祖,不同在于zip并不使用Latest最新的数据
例combineLatest
let firstPublisher = PassthroughSubject<Int, Never>()
let secondPublisher = PassthroughSubject<String, Never>()
firstPublisher
.combineLatest(secondPublisher)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
firstPublisher.send(1)
firstPublisher.send(2)
secondPublisher.send("a")
输出
(2, "a")
例 zip
let firstPublisher = PassthroughSubject<Int, Never>()
let secondPublisher = PassthroughSubject<String, Never>()
firstPublisher
.zip(secondPublisher)
.sink(receiveCompletion: { _ in
print("Finished")
}, receiveValue: { someValue in
print(someValue)
})
firstPublisher.send(1)
firstPublisher.send(2)
secondPublisher.send("a")
输出
(1, "a")
zip
数据序列中,最先进入的值优先组成元祖,而combineLatest
则是最新的值