[Combine 开发] collect、ignoreOutput的应用

collect

在 Combine 框架中,collect() 操作符用于将连续的元素组合成一个数组,并将这个数组作为一个事件发布给订阅者。collect一共有4种不同的用法:

1 .collect()

批处理数据: 当你希望以一定的批次处理来自数据源的元素时,可以使用 collect() 来将这些元素组成数组。这对于对批处理数据执行某些操作(例如平均值、总和等)非常有用

let numbers = (0...10)
let cancellable = numbers.publisher
    .collect()
    .sink { print("\($0)") }


// 结果: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

2 .collect(_:)

限制元素数量: 如果你只对从数据源接收的一定数量的元素感兴趣,而不是所有的元素,可以使用 collect(_:) 并指定要收集的元素数量 

let numbers = (0...10)
let cancellable = numbers.publisher
    .collect(3)
    .sink { print("\($0)") }

// 结果:
// [0, 1, 2]
// [3, 4, 5]
// [6, 7, 8]
// [9, 10]

3 .collect(.byTime(q, 2)) 

定时处理数据: 你可能需要每隔一段时间处理一次数据,而不是即时处理。这种情况下,你可以使用 .collect(.byTime) 来按时间定期收集元素

struct ContentView: View {
    let accelerometerData = PassthroughSubject<Int, Never>()
    var subscriptions = Set<AnyCancellable>()
    
    init() {
        accelerometerData
           .collect(.byTime(DispatchQueue.main, .seconds(2)))
           .sink { dataArray in
                   print("success:", dataArray)
           }
           .store(in: &subscriptions)
    }
    var body: some View {
        Button("Text") {
            accelerometerData.send(Int.random(in: 1...100))
        }
    }
}
  
// 结果:
// success: [33, 58, 78, 98, 85, 61, 99, 24]
// success: [72, 79, 11, 80, 38, 14, 23, 60, 36]
// success: [63, 85, 37, 38, 56, 52]
// success: [18, 84, 75, 100, 40]

4 .collect(.byTimeOrCount(q, 2, 3))

限制元素数量和时间: 有时候你可能同时关心在一定时间内和达到一定元素数量时进行处理。这时,.collect(.byTimeOrCount) 提供了一种方便的机制 

struct ContentView: View {
    let accelerometerData = PassthroughSubject<Int, Never>()
    var subscriptions = Set<AnyCancellable>()
    
    init() {
        accelerometerData
           .collect(.byTimeOrCount(DispatchQueue.main, .seconds(2), 3))
           .sink { dataArray in
                   print("success:", dataArray)
           }
           .store(in: &subscriptions)
    }
    var body: some View {
        Button("Text") {
            accelerometerData.send(Int.random(in: 1...100))
        }
    }
}

// 结果: 
// success: [15, 76, 44]
// success: [72, 52, 91]
// success: [14]
// success: [58, 21, 5]
// success: [58, 72, 29]
// success: [67, 39, 47]
// success: [29, 77]

ignoreOutput

仅关心完成事件: 有时候,我们只关心一个异步操作是否成功完成,而不关心实际的输出值。比如,一个网络请求成功完成,但返回的数据对我们来说并不重要,这时可以使用 ignoreOutput

let numbers = [1, 2, 3, 4, 5, 0, 6, 7, 8, 9]
let cancellable = numbers.publisher
    .ignoreOutput()
    .sink(receiveCompletion: {print("completion: \($0)")},
          receiveValue: {print("value \($0)")})

// 结果:completion: finished

ignoreOutput 操作符是 Combine 框架中一个简洁而强大的工具,它允许我们轻松地过滤不需要处理的输出元素,专注于完成或错误事件。通过在适当的场景中使用 ignoreOutput,我们可以写出更加清晰、简洁的异步代码,提高代码的可读性和可维护性。

应用场景:仅关心完成事件、完成后执行某些操作、忽略某个时间段内的输出

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值