msmialko
msmialko

Reputation: 1609

Swift Combine - combining publishers without waiting for all publishers to emit first element

I'm combining two publishers:

let timer = Timer.publish(every: 10, on: .current, in: .common).autoconnect()
let anotherPub: AnyPublisher<Int, Never> = ...

Publishers.CombineLatest(timer, anotherPub)
    .sink(receiveValue: (timer, val) in { 
      print("Hello!")
} )

Unfortunately, sink is not called until both publishers emit at least one element.

Is there any way to make the sink being called without waiting for all publishers? So that if any publisher emits a value, sink is called with other values set to nil.

Upvotes: 4

Views: 1962

Answers (1)

Charles Maria
Charles Maria

Reputation: 2195

You can use prepend(…) to prepend values to the beginning of a publisher.

Here's a version of your code that will prepend nil to both publishers.

let timer = Timer.publish(every: 10, on: .current, in: .common).autoconnect()
let anotherPub: AnyPublisher<Int, Never> = Just(10).delay(for: 5, scheduler: RunLoop.main).eraseToAnyPublisher()

Publishers.CombineLatest(
    timer.map(Optional.init).prepend(nil),
    anotherPub.map(Optional.init).prepend(nil)
)
.filter { $0 != nil && $1 != nil } // Filter the event when both are nil values
.sink(receiveValue: { (timer, val) in
    print("Hello! \(timer) \(val)")
})

Upvotes: 6

Related Questions