我通过组合创建了一个计时器,它Date使用以下代码发出和忽略错误:
let timer: AnyPublisher<Date, Never> = Timer.publish(every: 5, on: .main, in: RunLoop.Mode.common)
.autoconnect()
.map { _ in Date() }
.replaceError(with: Date())
.eraseToAnyPublisher()
Run Code Online (Sandbox Code Playgroud)
(我确信有比映射和替换错误更好的方法,但对于这个例子,我想保持类型简单,AnyPublisher<Date, Never>.)
计时器正确触发,但从创建计时器到第一次触发(即等待 5 秒)之间存在延迟。使用NSTimer,我们可以调用 timer.fire()来强制它立即触发。
是否有等效的方法来强制计时器在使用时立即发布Timer.publish()?
或者,有没有办法Just(Date())与上述合并,Timer.publish以便它立即每 5 秒触发一次,同时仍然保持AnyPublisher<Date, Never>类型?
小智 14
另外,还有一个使用prepend 的选项
let delayPublisher = Timer.publish(every: 5, on: .main, in: .common)
.autoconnect()
.receive(on: RunLoop.main)
.prepend(Date())
Run Code Online (Sandbox Code Playgroud)
我确信有比映射和替换错误更好的方法
Timer.TimerPublisher.Failureis Never,因此您不需要任何映射,因为它不会失败。
此外,Timer.TimerPublisher.Output已经是当前的Date(),所以你也不需要map输出。
要在订阅时立即发出当前日期,您需要将 aDeferred { Just(Date()) }与计时器发布者结合起来。这Deferred意味着在订阅发生之前不会计算当前日期。
这是将所有内容放在一起的一种方法:
let timer = Deferred { Just(Date()) }
.append(Timer.publish(every: 5, on: .main, in: .common).autoconnect())
.eraseToAnyPublisher()
Run Code Online (Sandbox Code Playgroud)
除了 @rob mayoff 答案和 @Senseful 评论,可以合并计时器执行的“第一个值”:
let delayPublisher = Timer.publish(every: 5, on: .main, in: .common)
.autoconnect()
.receive(on: RunLoop.main)
.merge(with: Just(Date()))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
800 次 |
| 最近记录: |