Буфер «буферизует» значения до своего размера, учитывая обратное давление в нисходящем направлении.
Таким образом, он обеспечивает разрыв (буфер?) Между тем, что отправляет восходящий поток, и тем, что нисходящий поток готов к принять. Timer
просто отбрасывает значения, если нисходящий поток не готов принять, но Buffer
готов к приему (до его возможностей с .keepFull
, или всегда / неограниченно со стратегией предварительной выборки .byRequest
)
В частности, в этом примере, если мы передаем значения из Timer
напрямую, буфер примет все начальные результаты (начальные результаты будут с интервалом 0,2 мс c), прежде чем будут заполнены и установлены в установившееся состояние (2 сек c друг от друга).
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)
}
При этом мне не совсем понятно, что хороший вариант использования - .keepFull
против .byRequest
.