首页 > 解决方案 > 将框架缓冲区运算符与 keepFull 策略相结合:它有什么作用?

问题描述

我的测试平台如下所示:

var storage = Set<AnyCancellable>()
override func viewDidLoad() {
    let pub = Timer.publish(every: 0.2, on: .main, in: .common).autoconnect()
        .scan(0) {i,_ in i+1}
        .buffer(size: 4, prefetch: .keepFull, whenFull: .dropNewest)
        .flatMap(maxPublishers:.max(1)) {
            Just($0).delay(for: 2, scheduler: DispatchQueue.main)
        }
    pub.sink{print($0)}.store(in:&storage)
}

结果只是连续缓慢而稳定的数字流:1 2 3 4 5 6 ...

.buffer但是,如果您只是完全删除该行,您会得到相同的结果。那么缓冲区有什么作用呢?换句话说:有人可以给我举个例子,说明带有.keepFull预取策略的缓冲区会产生影响吗?

标签: ioscombine

解决方案


缓冲区“缓冲区”值达到其大小,同时尊重下游的背压。

通过这种方式,它在上游发送的内容和下游准备接受的内容之间提供了一个间隙(缓冲区?)。如果下游尚未准备好接受,但已Timer准备好接受,则只会删除值(使用预取策略达到其容量,或始终/无限制)Buffer .keepFull.byRequest

具体来说,在本例中,如果我们Timer直接传递来自的值,缓冲区将接受所有初始结果(初始结果将相隔 0.2 秒),然后才被填充并稳定到稳态(相隔 2 秒)。

Timer.publish(every: 0.2, on: .main, in: .common).autoconnect()
    .buffer(size: 4, prefetch: .keepFull, whenFull: .dropNewest)
    .flatMap(maxPublishers:.max(1)) {
        Just($0).delay(for: 2, scheduler: DispatchQueue.main)
    }

这是另一个例子PassthroughSubject

let subject = PassthroughSubject<Int, Never>()

let c = subject
           //.buffer(size: 4, prefetch: .keepFull, whenFull: .dropNewest)
           .flatMap(maxPublishers:.max(1)) { 
               Just($0).delay(for: 2, scheduler: DispatchQueue.main) 
           }
           .sink { print($0) }

subject.send(1)
subject.send(2) // 2 would be dropped without the buffer

DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
   subject.send(3)
}

话虽如此,我并不完全清楚.keepFullvs的一个好的用例是什么.byRequest


推荐阅读