Combine操作符switchToLatest示例


2天前 4次点击 来自 移动端

标签: Swift

switchToLatest 接收publisher,输出具体的值,当接收到新的publisher后,switchToLatest会指向新的publisher,并同时取消之前的publisher

典型使用场景为搜索,搜索关键字会不断变化,当上一个搜索请求还没返回结果时此时又发起了新的搜索请求,那么将取消最后一次网络请求。

以下为官方示例

let subject = PassthroughSubject<Int, Never>()

let cancellable = subject
    .setFailureType(to: URLError.self)
    .map { index -> URLSession.DataTaskPublisher in
        let url = URL(string: "https://example.org/get?index=\(index)")!
        return URLSession.shared.dataTaskPublisher(for: url)
    }
    .switchToLatest()
    .sink(receiveCompletion: {
        print("Complete: \($0)")
    }, receiveValue: { _, response in
        guard let url = response.url else {
            print("Bad response.")
            return
        }
        print("URL: \(url)")
    })

for index in 1 ... 5 {
    DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(index / 10)) {
        subject.send(index)
    }
}

与它相对应的是flatMap,它返回一个publisher,当该publisher有值的时候,就会流向下游

let subject = PassthroughSubject<Int, Never>()

let cancellable = subject
    .setFailureType(to: URLError.self)
    .flatMap { index -> URLSession.DataTaskPublisher in
        let url = URL(string: "https://example.org/get?index=\(index)")!
        return URLSession.shared.dataTaskPublisher(for: url)
    }
    .sink(receiveCompletion: {
        print("Complete: \($0)")
    }, receiveValue: { _, response in
        guard let url = response.url else {
            print("Bad response.")
            return
        }
        print("URL: \(url)")
    })

for index in 1 ... 5 {
    DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(index / 10)) {
        subject.send(index)
    }
}

最后根据网络请求快慢返回5个请求结果,而switchToLatest只会返回1个请求结果

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1