And*_*can 2 delay publish-subscribe combine
TL; 博士
我想推迟发表,但不知道如何,呃,把这些部分结合起来
简单来说
我有一个 Publisher
let generator = PassthroughSubject<Bool, Never>()
Run Code Online (Sandbox Code Playgroud)
并想以某种方式使用修饰符
.delay(for: 2, scheduler: RunLoop.main)
Run Code Online (Sandbox Code Playgroud)
所以当我打电话
generator.send(true)
Run Code Online (Sandbox Code Playgroud)
消息在呼叫后两秒发送 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
您可以使用发布者的 debounce 属性来延迟发布。
$yourProperty
.debounce(for: 0.8, scheduler: RunLoop.main)
.eraseToAnyPublisher()
Run Code Online (Sandbox Code Playgroud)
.delay(for: 2, scheduler: RunLoop.main)可能正是您所需要的,但关键是要了解您如何订阅以完全了解问题。send()与主题一起使用时,延迟不会延迟值的发送- 这是命令式代码的链接,并在send调用时发送数据,通常针对某些已经存在的订阅。
虽然您在代码的第一位中有一个订阅者,但没有一个主题可以将它们固定在一起。
例如,如果您更新:
Just(false).dropFirst().eraseToAnyPublisher()
到
Just(false).dropFirst().eraseToAnyPublisher().delay(for: 2, scheduler: RunLoop.main)
然后打印语句应该在调用 init() 后约 2 秒触发。根据您在此处尝试完成的工作,使用闭包触发器(例如onAppear可能会发送更多),调用subject.send(),然后您可以根据需要在发布者链中延迟任何订阅它之前发生的事情。
| 归档时间: |
|
| 查看次数: |
5622 次 |
| 最近记录: |