Combine -- 错误处理

2021-02-22  本文已影响0人  jancywen

Combine 中提供了 Fail 这个内建的基础 Publisher,它所做的事情就是在被订阅时发送一个错误事件

Fail<Int, SampleError>(error: .sampleError)

错误转换

Subscriber 在订阅上游 Publisher 时,不仅需要保证 Publisher.Output 的类型和 Subscriber.Input 的类型一致,也要保证两者所接受的 Failure 也具有相同类型。

map 对 Output 进行转换,mapError 对 Failure 进行转换,

Fail<Int, SampleError>(error: .sampleError)
  .mapError { _ in MyError.myError }

抛出错误

当你有需求在数据转换或者处理时,将事件流以错误进行终止,都可以使用对应操作的 try 版本来进行抛出,并在订阅者一侧接收到对应的错误事件。比如 tryMap、tryScan、tryFilter、tryReduce 等等

check("Throw") {
  ["1", "2", "Swift", "4"]
    .publisher 
    .tryMap { s -> Int in 
      guard let value = Int(s) else { 
        throw MyError.myError 
      } 
      return value
   } 
}
// 输出: 
// ----- Throw ----- 
// receive subscription: (TryMap) 
// request unlimited 
// receive value: (1) 
// receive value: (2) 
// receive error: (myError)

从错误中恢复

  1. .replaceError(with: ) 使用默认值来让事件流从错误中 “恢复”。
check("Throw") {
  ["1", "2", "Swift", "4"]
    .publisher 
    .tryMap { s -> Int in 
      guard let value = Int(s) else { 
        throw MyError.myError 
      } 
      return value
   } 
   .replaceError(with: -1)
}
// 输出: 
// ----- Throw ----- 
// receive subscription: (TryMap) 
// request unlimited 
// receive value: (1) 
// receive value: (2) 
// receive value: (-1)
// receive finished
  1. catch 接受的是一个新的 Publisher,当上游 Publisher 发生错误时,catch 操作会使用新的Publisher来把原来的 Publisher 替换掉。
...
  .catch { _ in [-1, -2, -3].publisher }
...

恢复后续驱动

check("Catch and Continue") {
    ["1", "2", "some", "4"]
        .publisher
        .flatMap { s in
            return Just<String>(s)
                .tryMap {s -> Int in
                    guard let value = Int(s) else {
                        throw SampleError.sampleError
                    }
                    return value
                }
                .catch{_ in Just(-1)}
        }
}

// ----- Catch and Continue -----
// receive subscription: (FlatMap)
// request unlimited
// receive value: (1)
// receive value: (2)
// receive value: (-1)
// receive value: (4)
// receive finished
上一篇下一篇

猜你喜欢

热点阅读