[Combine 开发] combineLatest、merge、zip的使用区别

combineLatestmergezip 是三个常用的操作符,用于组合和处理流式数据。以下是它们的区别以及在 Combine 中的使用场景

combineLatest

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

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 操作符,用于将多个发布者的元素按顺序进行配对,形成元组

只有当所有发布者都发出了新元素时,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 是一个有用的操作符。例如,合并用户的用户名和密码进行认证

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-22 16:48:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-22 16:48:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-22 16:48:04       82 阅读
  4. Python语言-面向对象

    2024-01-22 16:48:04       91 阅读

热门阅读

  1. dp_day1

    2024-01-22 16:48:04       49 阅读
  2. DDD系列 - 第9讲 实体、值对象

    2024-01-22 16:48:04       61 阅读
  3. SQL笔记 -- 数据库结构优化

    2024-01-22 16:48:04       57 阅读
  4. Go 语言实现冒泡排序算法的简单示例

    2024-01-22 16:48:04       69 阅读
  5. 部署Golang服务

    2024-01-22 16:48:04       56 阅读
  6. 面试题-MySQL如何定位慢查询

    2024-01-22 16:48:04       56 阅读
  7. htb Analysis wp

    2024-01-22 16:48:04       35 阅读
  8. php.2安装Imagick扩展

    2024-01-22 16:48:04       59 阅读
  9. 计算机视觉未来的走向

    2024-01-22 16:48:04       51 阅读