TL;DR
我想推迟出版,但不知道如何,呃,合并的部分
简要
我有一个Publisher
let generator = PassthroughSubject<Bool, Never>()
想用修饰语
.delay(for: 2, scheduler: RunLoop.main)
这样我打电话的时候
generator.send(true)
消息在呼叫send()
两秒钟后发送
查看Publishers.Delay
的文档可以更清楚地看到类型错误,但并不能帮助我找到正确的方法来连接。
编码
import SwiftUI
import Combine
// Exists just to subscribe.
struct ContainedView : View {
private let publisher: AnyPublisher<Bool, Never>
init(_ publisher: AnyPublisher<Bool, Never> = Just(false).dropFirst().eraseToAnyPublisher()) {
self.publisher = publisher
}
var body: some View {
Rectangle().onReceive(publisher) { _ in print("Got it") }
}
}
struct ContentView: View {
let generator = PassthroughSubject<Bool, Never>()
// .delay(for: 2, scheduler: RunLoop.main)
// Putting it here doesn't work either.
var body: some View {
VStack {
Button("Tap") {
// Does not compile
self.generator.delay(for: 2, scheduler: RunLoop.main).send(true)
// Value of type 'Publishers.Delay<PassthroughSubject<Bool, Never>, RunLoop>' has no member 'send'
// https://developer.apple.com/documentation/combine/publishers/delay
// Does not compile
self.generator.send(true).delay(for: 2, scheduler: RunLoop.main)
// Value of tuple type '()' has no member 'delay'
// Just a broken-up version of the first try.
let delayed = self.generator.delay(for: 2, scheduler: RunLoop.main)
delayed.send(true)
// This, of course, builds and works.
self.generator.send(true)
print("Sent it")
}
ContainedView(generator.eraseToAnyPublisher())
.frame(width: 300, height: 200)
}
}
}
3条答案
按热度按时间vcudknz31#
.delay(for: 2, scheduler: RunLoop.main)
很可能正是您所需要的,但要完全理解这个问题,关键是要了解您是如何订阅的。当使用带有主题的send()
时,Delay不会延迟发送值-这是命令式代码的链接,每当调用send
时都会发送数据,通常是针对一些已经存在的订阅。虽然在代码的第一位有一个订阅者,但没有一个订阅者带有将这些绑定在一起的主题。
例如,如果更新了:
Just(false).dropFirst().eraseToAnyPublisher()
到
Just(false).dropFirst().eraseToAnyPublisher().delay(for: 2, scheduler: RunLoop.main)
那么print语句应该在init()被调用后2秒左右触发。根据你在这里试图完成的任务,使用一个闭包触发器,比如
onAppear
可能会更有意义,让它调用subject.send()
,然后你可以在发布者链中延迟它,在任何订阅它之前发生。zed5wv102#
可以使用发布服务器的反跳属性来延迟发布。
mnemlml83#
输出