Swift合并-延迟发布者

zzoitvuj  于 2023-04-10  发布在  Swift
关注(0)|答案(3)|浏览(165)

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)
        }
    }
}
vcudknz3

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(),然后你可以在发布者链中延迟它,在任何订阅它之前发生。

zed5wv10

zed5wv102#

可以使用发布服务器的反跳属性来延迟发布。

$yourProperty
    .debounce(for: 0.8, scheduler: RunLoop.main)
    .eraseToAnyPublisher()
mnemlml8

mnemlml83#

let generator = PassthroughSubject<Bool, Never>()
let generated = generator.delay(for: 2, scheduler: RunLoop.main).sink { value in
    print(value.description + " " + Date().timeIntervalSinceReferenceDate.description)
}
print(Date().timeIntervalSinceReferenceDate.description)
generator.send(true)
generator.send(false)

输出

641453284.840604
true 641453286.841731
false 641453286.847715

相关问题