Combine操作符Mixing示例


2天前 8次点击 来自 移动端

标签: 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则是最新的值

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1