一个 Combine Publisher,通过在输出之间插入延迟来限制吞吐量。
与 throttle(for:scheduler:latest:)
和 debounce(for:scheduler:options:)
不同,delayOutput(for:tolerance:scheduler:options:)
不会丢弃输出元素。
第一个输出元素将被立即调度。后续元素可能会被指定的间隔延迟。
使用 Publisher 的 delayOutput(for:tolerance:scheduler:options:)
方法来获取一个 DelayOutputPublisher。
第一个输出将被立即调度,任何后续输出将在上次输出传递完成后(在 subscriber.receive()
返回后)被调度。
let df = DateFormatter()
df.dateStyle = .none
df.timeStyle = .medium
print("Start at \(df.string(from: Date()))")
let cancellable = (0..<4).publisher
.delayOutput(for: .seconds(1), scheduler: RunLoop.main)
.sink(
receiveCompletion: { print("completed \($0)") },
receiveValue: { value in
print("Received \(value) after \(df.string(from: Date()))")
})
输出
Start at 18:22:21
Received 0 after 18:22:21
Received 1 after 18:22:22
Received 2 after 18:22:23
Received 3 after 18:22:24
completed finished
一个 SwiftUI 示例,展示了如何限制
class SlowCounter: ObservableObject {
private let subject: PassthroughSubject<Int, Never>
let delayed: DelayOutputPublisher<PassthroughSubject<Int, Never>, RunLoop>
init() {
subject = PassthroughSubject<Int, Never>()
delayed = subject
.delayOutput(for: .seconds(1), scheduler: RunLoop.main)
}
private(set) var count = 0
func addOne() {
count += 1
subject.send(count)
}
}
struct MyView: View {
@ObservedObject var counter = SlowCounter()
@State var count = 0
var body: some View {
Text("Hello \(count)")
.onReceive(counter.delayed) { count = $0 }
Button("Increase!") {
counter.addOne()
}
}
}
编辑 Package.swift 文件。 将 DelayOutputPublisher 添加为依赖项
let package = Package(
name: " ... ",
products: [ ... ],
dependencies: [
.package(url: "https://github.com/berikv/DelayOutputPublisher.git", from: "1.0.0") // here
],
targets: [
.target(
name: " ... ",
dependencies: [
"DelayOutputPublisher" // and here
]),
]
)