debounce
debounce 又叫做 “防抖”:Publisher 在接收到第一个值后,并不是立即将它发布出去,而是会开启一个内部计时器,当一定时间内没有新的事件来到,再将这个值进行发布。如果在计时期间有新的事件,则重置计时器并重复上述等待过程。
extension String {
//将原始的url编码为合法的url
public func urlEncoded() -> String? {
let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
return encodeUrlString
}
//将编码后的url转换回原始的url
public func urlDecoded() -> String? {
return self.removingPercentEncoding
}
// 去除首尾空格
public func removeWhitespaces() -> String {
return self.trimmingCharacters(in: .whitespaces)
}
}
struct Response: Decodable {
struct Args: Decodable {
let foo: String
}
let args: Args?
}
let searchText = PassthroughSubject<String, Never>()
searchText
.scan("", { "\($0) \($1)"})
.debounce(for: .seconds(3), scheduler: RunLoop.main)
.compactMap{$0.removeWhitespaces().urlEncoded()}
.flatMap { text in
return URLSession.shared
.dataTaskPublisher(for: URL(string: "https://httpbin.org/get?foo=\(text)")!)
.subscribe(on: RunLoop.main)
.map{data, _ in data}
.decode(type: Response.self, decoder: JSONDecoder())
.compactMap{$0.args?.foo.urlDecoded()}
.replaceError(with: text)
}.eraseToAnyPublisher()
.subscribe(on: RunLoop.main)
.print()
.sink(receiveValue: {_ in})
delay(0) { searchText.send("I") }
delay(1) { searchText.send("Love") }
delay(2) { searchText.send("SwiftUI") }
delay(6) { searchText.send("And") }
delay(8) { searchText.send("Combine") }
// 输出:
// receive subscription: (SubscribeOn)
// request unlimited
// receive value: (I Love SwiftUI)
// receive value: (I Love SwiftUI And Combine)
throttle
在指定的时间间隔内有选择地从上游发布者重新发布元素。在收到一个事件后开始计时,并忽略计时周期内的后续输入。
extension Publisher {
/// Publishes either the most-recent or first element published by the upstream publisher in the specified time interval.
///
/// - Parameters:
/// - interval: The interval at which to find and emit the most recent element, expressed in the time system of the scheduler.
/// - scheduler: The scheduler on which to publish elements.
/// - latest: A Boolean value that indicates whether to publish the most recent element. If `false`, the publisher emits the first element received during the interval.
/// - Returns: A publisher that emits either the most-recent or first element received during the specified interval.
public func throttle<S>(for interval: S.SchedulerTimeType.Stride, scheduler: S, latest: Bool) -> Publishers.Throttle<Self, S> where S : Scheduler
}
网友评论