2020年12月20日星期日

How to compose a combine publisher that emits the last-emitted value to its 2nd subscriber

I'm trying to compose a publisher, that, when a subsequent subscriber connects to it, emits the last emitted value immediately to that subscriber, and then continues to emit future values to all connected subscribers.

Q: Is there a way to do this without writing a publisher from scratch, and only by composing built-in publishers? I might be missing something here.

So, if we had a publisher counting every second:

let counter = Timer.publish(every: 1, on: .main, in: .common)                     .autoconnect()                     .scan(0, { v, _ in v + 1 })      let sharedPublisher = // ??? something with counter publisher above    sharedPublisher.sink { print("A: ", $0 }.store(in: &bag)    // after 2.5 seconds  sharedPublisher.sink { print("B: ", $0 }.store(in: &bag)  

The output would be:

A: 1 // at t=1 sec  A: 2 // at t=2  B: 2 // at t=2.5  A: 3 // at t=3  B: 3 // at t=3  

Initially, naively, I thought I could just use a .share and a .buffer:

let sharedPublisher = counter                    .share()                    .buffer(size: 1, prefetch: .byRequest, whenFull: .dropOldest)  

but of course, that doesn't work since buffer only buffers if the downstream isn't ready to accept values, which isn't the case here. Maybe something with Record/Record.Recording?

https://stackoverflow.com/questions/65386645/how-to-compose-a-combine-publisher-that-emits-the-last-emitted-value-to-its-2nd December 21, 2020 at 09:54AM

没有评论:

发表评论