将框架缓冲区运算符与keepFull策略结合使用:它有什么作用? [英] Combine framework buffer operator with keepFull strategy: what does it do?

查看:50
本文介绍了将框架缓冲区运算符与keepFull策略结合使用:它有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的测试台看起来像这样:

My testbed looks like this:

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 ...

The result is just a slow steady stream of numbers in succession: 1 2 3 4 5 6 ...

但是,如果您完全删除 .buffer 行,您将得到相同的结果.那么缓冲区的作用是什么?换句话说:有人可以给我一个例子,其中带有 .keepFull 预取策略的缓冲区会有所作为吗?

But that is the same result you would get if you just deleted the .buffer line entirely. So what purpose does the buffer serve? To put it another way: can someone make me an example where a buffer with a .keepFull prefetch policy makes a difference?

推荐答案

缓冲区"buffers"重视其尺寸,同时尊重下游的背压.

Buffer "buffers" values up to its size, while respecting downstream's back-pressure.

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

In this way it provides a gap (a buffer?) between what the upstream sends and what the downstream is ready to accept. Timer would just drop values if downstream isn't ready to accept, but Buffer is ready to accept (up to its capacity with .keepFull, or always/unlimited with .byRequest prefetch strategy)

具体来说,在此示例中,如果我们直接从 Timer 中传递值,则在填充并稳定为稳定值之前,buffer将接受所有初始结果(初始结果相隔0.2毫秒).状态(相隔2秒).

Specifically, in this example, if we passed the values from Timer directly, buffer would accept all the initial results (initial results would be 0.2 msec apart), before getting filled and settling into a steady-state (2 sec apart).

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 的示例:

Here's another example with 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)
}

话虽这么说,对我来说, .keepFull .byRequest 的好用例是什么还不清楚.

That being said, it's not entirely clear to me what a good use case is for .keepFull vs .byRequest.

这篇关于将框架缓冲区运算符与keepFull策略结合使用:它有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆