Reputation: 91711
I created a timer via combine which emits Date
and ignores errors using this code:
let timer: AnyPublisher<Date, Never> = Timer.publish(every: 5, on: .main, in: RunLoop.Mode.common)
.autoconnect()
.map { _ in Date() }
.replaceError(with: Date())
.eraseToAnyPublisher()
(I'm sure there are better ways than mapping and replacing the error, but for this example, I wanted to keep the type simple, AnyPublisher<Date, Never>
.)
The timer fires correctly, but there is a delay between when the timer is created to when it fires the first time (i.e. it waits 5 seconds). With NSTimer, we can invoke timer.fire() to force it to fire immediately.
Is there an equivalent way to force a timer to post immediately when using Timer.publish()
?
Alternatively, is there a way to merge Just(Date())
with the above Timer.publish
so that it fires immediately and every 5 seconds, while still keeping the AnyPublisher<Date, Never>
type?
Upvotes: 13
Views: 3662
Reputation: 509
Also, there is an option using prepend
let delayPublisher = Timer.publish(every: 5, on: .main, in: .common)
.autoconnect()
.receive(on: RunLoop.main)
.prepend(.now)
Upvotes: 19
Reputation: 1110
Alternative to @rob mayoff answer and @Senseful comment, it's possible to merge the "first value" of the timer doing:
let delayPublisher = Timer.publish(every: 5, on: .main, in: .common)
.autoconnect()
.receive(on: RunLoop.main)
.merge(with: Just(Date()))
Upvotes: 6
Reputation: 385700
I'm sure there are better ways than mapping and replacing the error
Timer.TimerPublisher.Failure
is Never
, so you don't need any mapping because it can't fail.
Furthermore, Timer.TimerPublisher.Output
is already the current Date()
, so you don't need to map
the output either.
To emit the current date immediately on subscription, you want to combine a Deferred { Just(Date()) }
with the timer publisher. The Deferred
means the current date won't be computed until the subscription happens.
Here is one way to put it all together:
let timer = Deferred { Just(Date()) }
.append(Timer.publish(every: 5, on: .main, in: .common).autoconnect())
.eraseToAnyPublisher()
Upvotes: 13