美文网首页
Combine -- 限流

Combine -- 限流

作者: jancywen | 来源:发表于2021-02-24 09:34 被阅读0次

    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
    }
    

    相关文章

      网友评论

          本文标题:Combine -- 限流

          本文链接:https://www.haomeiwen.com/subject/zjrkfltx.html