[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()
    var subscriptions = Set()
    
    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()
    var subscriptions = Set()
    
    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,我们可以写出更加清晰、简洁的异步代码,提高代码的可读性和可维护性。

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

你可能感兴趣的:(combine,swift)