将框架缓冲区运算符与 keepFull 策略相结合:它有什么作用?
Combine framework buffer operator with keepFull strategy: what does it do?
我的测试平台是这样的:
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([=10=]).delay(for: 2, scheduler: DispatchQueue.main)
}
pub.sink{print([=10=])}.store(in:&storage)
}
结果只是一个缓慢稳定的连续数字流:1 2 3 4 5 6 ...
但这与完全删除 .buffer
行会得到相同的结果。那么缓冲区的作用是什么?换句话说:有人可以给我举个例子,其中带有 .keepFull
预取策略的缓冲区会有所不同吗?
缓冲区“缓冲”值至其大小,同时尊重下游的 back-pressure。
通过这种方式,它在上游发送的内容和下游准备接受的内容之间提供了一个间隙(缓冲区?)。如果下游还没有准备好接受,Timer
只会丢弃值,但是 Buffer
是 准备好接受(达到其容量 .keepFull
,或 always/unlimited 使用 .byRequest
预取策略)
具体来说,在这个例子中,如果我们直接传递来自 Timer
的值,缓冲区将接受所有初始结果(初始结果相隔 0.2 秒),然后填充并进入 steady-state(相隔 2 秒)。
Timer.publish(every: 0.2, on: .main, in: .common).autoconnect()
.buffer(size: 4, prefetch: .keepFull, whenFull: .dropNewest)
.flatMap(maxPublishers:.max(1)) {
Just([=10=]).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([=11=]).delay(for: 2, scheduler: DispatchQueue.main)
}
.sink { print([=11=]) }
subject.send(1)
subject.send(2) // 2 would be dropped without the buffer
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
subject.send(3)
}
话虽这么说,但我并不完全清楚 .keepFull
与 .byRequest
.
哪个是好的用例
我的测试平台是这样的:
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([=10=]).delay(for: 2, scheduler: DispatchQueue.main)
}
pub.sink{print([=10=])}.store(in:&storage)
}
结果只是一个缓慢稳定的连续数字流:1 2 3 4 5 6 ...
但这与完全删除 .buffer
行会得到相同的结果。那么缓冲区的作用是什么?换句话说:有人可以给我举个例子,其中带有 .keepFull
预取策略的缓冲区会有所不同吗?
缓冲区“缓冲”值至其大小,同时尊重下游的 back-pressure。
通过这种方式,它在上游发送的内容和下游准备接受的内容之间提供了一个间隙(缓冲区?)。如果下游还没有准备好接受,Timer
只会丢弃值,但是 Buffer
是 准备好接受(达到其容量 .keepFull
,或 always/unlimited 使用 .byRequest
预取策略)
具体来说,在这个例子中,如果我们直接传递来自 Timer
的值,缓冲区将接受所有初始结果(初始结果相隔 0.2 秒),然后填充并进入 steady-state(相隔 2 秒)。
Timer.publish(every: 0.2, on: .main, in: .common).autoconnect()
.buffer(size: 4, prefetch: .keepFull, whenFull: .dropNewest)
.flatMap(maxPublishers:.max(1)) {
Just([=10=]).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([=11=]).delay(for: 2, scheduler: DispatchQueue.main)
}
.sink { print([=11=]) }
subject.send(1)
subject.send(2) // 2 would be dropped without the buffer
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
subject.send(3)
}
话虽这么说,但我并不完全清楚 .keepFull
与 .byRequest
.