Combine 为我们提供了一些便捷的 Publisher 的实现
- just
let justPubliser = Publishers.Just("Hello")
justPubliser 会给每个订阅者发送一个 "Hello" 消息,然后立即结束(这个数据流只包含一个值)。
- Empty
Empty 不提供任何值的更新,并且可以选择立即正常结束。
Once
Once 可以提供以下两种数据流之一:
发送一次值更新,然后立即正常结束(和 Just 一样)
- 立即因错误而终止
- Fail
Fail 和 Once 很像,也是提供两种情况之一:
- 发送一次值更新,然后立即因错误而终止
- 立即因错误而终止
Sequence
Sequence 将给定的一个序列按序通知到订阅者。
- Future
Future 初始化需要提供执行具体操作的 closure,这个操作可以是异步的,并且最终返回一个 Result,所以 Future 要么发送一个值,然后正常结束,要么因错误而终止。在将一些异步操作转换为 Publisher 时非常有用,尤其是网络请求。例如:
let apiRequest = Publishers.Future { promise in
URLSession.shared.dataTask(with: url) { data, _, _ in
promise(.success(data))
}.resume()
}
Deferred
Deferred 初始化需要提供一个生成 Publisher 的 closure,只有在有 Subscriber 订阅的时候才会生成指定的 Publisher,并且每个 Subscriber 获得的 Publisher 都是全新的。
那么,在之前的 Just Publisher 例子中,假设我们要实现延迟两秒后再发送消息呢?也很简单。我们前面说到 Publisher 都是可以组合变换的,这些组合变换可以通过操作符来实现的。
上面的例子利用 delay 操作符就可以改写为:
let delayedJustPublisher = justPubliser.delay(for: 2, scheduler: DispatchQueue.main)
- map/mapError
map 将收到的值按照给定的 closure 转换为其他值,mapError 则将错误转换为另外一种错误类型。
func map<T>(_ transform: (Output) -> T) -> Publishers.Just<T>
replaceNil
replaceNil 将收到的 nil 转换为给定的值。
func replaceNil<T>(with output: T) -> Publishers.Map<Self, T> where Self.Output == T?
scan
scan 将收到的值与当前的值(第一次使用 initialResult )按照给定的 closure 进行转换。
func scan<T>(_ initialResult: T, _ nextPartialResult: @escaping (T, Self.Output) -> T) -> Publishers.Scan<Self, T>
setFailureType
setFailureType 强制将上游 Publisher 的错误类型设置为指定类型。这个方法并不是进行错误类型的转换,因为它并没有让我们提供一个 closure,实际上只是为了让不同的 Publisher 的错误类型进行统一,因而这个 Publisher 实际上是不应该发生错误的。
func scan<T>(_ initialResult: T, _ nextPartialResult: @escaping (T, Self.Output) -> T) -> Publishers.Scan<Self, T>
filter
filter 只会让满足条件的值通过。
func filter(_ isIncluded: @escaping (Self.Output) -> Bool) -> Publishers.Filter<Self>