赞
踩
Combine 系列
目的: flatMap
操作符可以与 catch
一起使用,以持续处理新发布的值上的错误。
flatMap 是用于处理持续事件流中错误的操作符。
你提供一个闭包给 flatMap
,该闭包可以获取所传入的值,并创建一个一次性的发布者,完成可能失败的工作。 这方面的一个例子是从网络请求数据,然后将其解码。 你可以引入一个 catch
操作符,以捕获任何错误并提供适当的值。
当你想要保持对上游发布者的更新时,这是一个完美的机制,因为它创建一次性的发布者或短管道,发送一个单一的值,然后完成每一个传入的值。 所创建的一次性发布者的完成事件在 flatMap
中终止,并且不会传递给下游订阅者。
一个使用 dataTaskPublisher
的这样的例子:
let remoteDataPublisher = Just(self.testURL!) // 1 .flatMap { url in // 2 URLSession.shared.dataTaskPublisher(for: url) // 3 .tryMap { data, response -> Data in // 4 guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { throw TestFailureCondition.invalidServerResponse } return data } .decode(type: PostmanEchoTimeStampCheckResponse.self, decoder: JSONDecoder()) // 5 .catch {_ in // 6 return Just(PostmanEchoTimeStampCheckResponse(valid: false)) } } .eraseToAnyPublisher()
Just
以传入一个 URL
作为示例启动此发布者。flatMap
以 URL 作为输入,闭包继续创建一次性发布者管道。dataTaskPublisher
使用输入的 url 发出请求。(Data, URLResponse)
元组)流入 tryMap
以解析其他错误。decode
尝试将返回的数据转换为本地定义的类型。catch
将把错误转换为一个默认的值。 在这个例子中,是具有预设好 valid = false
属性的对象。目的: 在 Apple 的 WWDC 2019 演示 Advances in Networking, Part 1 中,使用 tryCatch
和 tryMap
操作符提供了示例模式,以响应网络受到限制的特殊错误。
// Generalized Publisher for Adaptive URL Loading func adaptiveLoader(regularURL: URL, lowDataURL: URL) -> AnyPublisher<Data, Error> { var request = URLRequest(url: regularURL) // 1 request.allowsConstrainedNetworkAccess = false // 2 return URLSession.shared.dataTaskPublisher(for: request) // 3 .tryCatch { error -> URLSession.DataTaskPublisher in // 4 guard error.networkUnavailableReason == .constrained else { throw error } return URLSession.shared.dataTaskPublisher(for: lowDataURL) // 5 .tryMap { data, response -> Data in guard let httpResponse = response as? HTTPUrlResponse, // 6 httpResponse.statusCode == 200 else { throw MyNetworkingError.invalidServerResponse } return data } .eraseToAnyPublisher() // 7
在苹果的 WWDC 中的这个例子,提供了一个函数,接受两个 URL 作为参数 —— 一个主要的 URL 和一个备用的。 它会返回一个发布者,该发布者将请求数据,并在网络受到限制时向备用 URL 请求数据。
request
变量是一个尝试请求数据的 URLRequest
。request.allowsConstrainedNetworkAccess
将导致 dataTaskPublisher
在网络受限时返回错误。dataTaskPublisher
发起请求。tryCatch
用于捕获当前的错误状态并检查特定错误(受限的网络)。URL
创建一个新的一次性发布者。tryMap
可以基于对应到错误条件的 HTTP
响应码来抛出错误,将此映射为失败。eraseToAnyPublisher
可在操作符链上进行类型擦除,因此 adaptiveLoader
函数的返回类型为 AnyPublisher<Data, Error>
。在示例中,如果从原始请求返回的错误不是网络受限的问题,则它会将 .failure
结束事件传到管道中。 如果错误是网络受限,则 tryCatch
操作符会创建对备用 URL
的新请求。
https://heckj.github.io/swiftui-notes/index_zh-CN.html
https://github.com/heckj/swiftui-notes
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。