swift 中的两个处理异步调用中的错误如何组合?
How two handle errors in async calls in swift combine?
我有两个异步调用来从服务器获取数据,但我希望它们将它们作为单个响应来处理,还希望为每个响应处理错误。
例如,这里我有两个方法m1()
,m2()
每个方法都可以抛出不同类型的错误。
我们应该等待得到两者的响应 并根据其错误类型显示错误消息。如果没有错误,继续流程。
我们必须使用哪个运算符?我尝试使用 Publishers.Zip
& Publishers.Map
无法处理错误。
enum Error1: Error {
case e1
}
enum Error2: Error {
case e2
}
func m1() -> Future<Bool, Error1> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
promise(.failure(.e1))
}
}
}
func m2() -> Future<String, Error2> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
promise(.success("1"))
}
}
}
不胜感激。!!谢谢。
我认为您 运行 遇到的问题与 Publisher
只能发出一种错误类型这一事实有关。因此,任何时候您尝试组合 m1
和 m2
,每个都有不同的错误类型,那么您 运行 就会陷入类型冲突问题。
您可以选择多种方法来解决此问题。我要推荐一个。在我的解决方案中,您的每个请求(您的 Futures)都将使用 Never
的错误类型,但单个请求的成功或失败将在 Result
中进行。这是 Playground 中的代码:
import Foundation
import Combine
enum Error1: Error {
case e1
}
enum Error2: Error {
case e2
}
func m1(shouldFail: Bool) -> Future<Result<Bool, Error1>, Never> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
if(shouldFail) {
promise(.success(.failure(.e1)))
} else {
promise(.success(.success(true)))
}
}
}
}
func m2(shouldFail: Bool) -> Future<Result<String, Error2>, Never> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
if(shouldFail) {
promise(.success(.failure(.e2)))
} else {
promise(.success(.success("1")))
}
}
}
}
let subscribe = m1(shouldFail: false)
.zip(m2(shouldFail: true))
.sink {
(m1:Result<Bool, Error1>, m2:Result<String, Error2>) in
switch m1 {
case .success(let boolResult) :
print("M1 succeeded with result \(boolResult)")
case .failure(_) :
print("M1 failed")
}
switch m2 {
case .success(let stringResult) :
print("M2 succeeded with result \(stringResult)")
case .failure(_) :
print("M2 failed")
}
}
(请注意,我向您的 m1 和 m2 请求添加了一个 shouldFail
参数,以便您可以在一个或另一个请求失败时处理不同的情况)。
请注意,每个 Futures return 都是 Future<SomeKindOfResult, Never>
的一种。这意味着进入组合管道的期货具有相同的错误类型(恰好是 Never
)。这导致看起来非常奇怪的结构:
promise(.success(.failure(.e1)))
这有点奇怪,但它说 Future 同意请求完成,并且 Result
包含该请求的成功或失败。
管道使用 zip
等待两个请求完成。来自 zip
的值是一个元组 (Result<Bool, Error1>, Result<String, Error2>
。此元组准确地表示每个请求的成功或失败,并在每种情况下携带适当的值。
我有两个异步调用来从服务器获取数据,但我希望它们将它们作为单个响应来处理,还希望为每个响应处理错误。
例如,这里我有两个方法m1()
,m2()
每个方法都可以抛出不同类型的错误。
我们应该等待得到两者的响应 并根据其错误类型显示错误消息。如果没有错误,继续流程。
我们必须使用哪个运算符?我尝试使用 Publishers.Zip
& Publishers.Map
无法处理错误。
enum Error1: Error {
case e1
}
enum Error2: Error {
case e2
}
func m1() -> Future<Bool, Error1> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
promise(.failure(.e1))
}
}
}
func m2() -> Future<String, Error2> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
promise(.success("1"))
}
}
}
不胜感激。!!谢谢。
我认为您 运行 遇到的问题与 Publisher
只能发出一种错误类型这一事实有关。因此,任何时候您尝试组合 m1
和 m2
,每个都有不同的错误类型,那么您 运行 就会陷入类型冲突问题。
您可以选择多种方法来解决此问题。我要推荐一个。在我的解决方案中,您的每个请求(您的 Futures)都将使用 Never
的错误类型,但单个请求的成功或失败将在 Result
中进行。这是 Playground 中的代码:
import Foundation
import Combine
enum Error1: Error {
case e1
}
enum Error2: Error {
case e2
}
func m1(shouldFail: Bool) -> Future<Result<Bool, Error1>, Never> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
if(shouldFail) {
promise(.success(.failure(.e1)))
} else {
promise(.success(.success(true)))
}
}
}
}
func m2(shouldFail: Bool) -> Future<Result<String, Error2>, Never> {
return Future { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
if(shouldFail) {
promise(.success(.failure(.e2)))
} else {
promise(.success(.success("1")))
}
}
}
}
let subscribe = m1(shouldFail: false)
.zip(m2(shouldFail: true))
.sink {
(m1:Result<Bool, Error1>, m2:Result<String, Error2>) in
switch m1 {
case .success(let boolResult) :
print("M1 succeeded with result \(boolResult)")
case .failure(_) :
print("M1 failed")
}
switch m2 {
case .success(let stringResult) :
print("M2 succeeded with result \(stringResult)")
case .failure(_) :
print("M2 failed")
}
}
(请注意,我向您的 m1 和 m2 请求添加了一个 shouldFail
参数,以便您可以在一个或另一个请求失败时处理不同的情况)。
请注意,每个 Futures return 都是 Future<SomeKindOfResult, Never>
的一种。这意味着进入组合管道的期货具有相同的错误类型(恰好是 Never
)。这导致看起来非常奇怪的结构:
promise(.success(.failure(.e1)))
这有点奇怪,但它说 Future 同意请求完成,并且 Result
包含该请求的成功或失败。
管道使用 zip
等待两个请求完成。来自 zip
的值是一个元组 (Result<Bool, Error1>, Result<String, Error2>
。此元组准确地表示每个请求的成功或失败,并在每种情况下携带适当的值。