Combine核心概念

 

Combine主要有3大核心概念:PublisherOperatorSubscriber

 

  • Publisher是数据的提供者,它提供了最原始的数据,不管这个数据是从什么地方获取的。如果把pipline想象成一条包子生产线,那么Publisher就表示食材

  • Subscriber是数据的接收者,它要求接收的数据必须是处理好的,同样把pipline想象成一条包子生产线,则Subscriber就是成品包子,而不是中间产物(菜馅等)

  • Operator是中间处理过程,它上下联通Publisher和Subscriber,对Publisher输出地数据进行处理,然后返回成品数据给Subscriber

 

Publisher



public protocol Publisher {


    /// The kind of values published by this publisher.

    associatedtype Output


    /// The kind of errors this publisher might publish.

    ///

    /// Use `Never` if this `Publisher` does not publish errors.

    associatedtype Failure : Error


    /// Attaches the specified subscriber to this publisher.

    ///

    /// Implementations of ``Publisher`` must implement this method.

    ///

    /// The provided implementation of ``Publisher/subscribe(_:)-4u8kn``calls this method.

    ///

    /// - Parameter subscriber: The subscriber to attach to this ``Publisher``, after which it can receive values.

    func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input

}

 

从上边的代码,我们可以分析出3点重要信息:

 

  • Publisher是一个协议,我们后续用到的所有publishers都实现了这个协议

  • Publisher/receive(subscriber:)是该协议的核心方法,它接受的参数subscriber需要实现Subscriber协议,这就是OperatorSubscriber能够连接Publisher原因

  • Self.Failure == S.Failure, Self.Output == S.Input这个条件限制了Publisher输出的数据类型必须跟Subscriber输入的数据类型保持一致

 

Publisher/receive(subscriber:) 并没有限制Subscriber的数量,因此 Publisher 可以接受多个订阅。

 

Subscriber


 


public protocol Subscriber : CustomCombineIdentifierConvertible {


    /// The kind of values this subscriber receives.

    associatedtype Input


    /// The kind of errors this subscriber might receive.

    ///

    /// Use `Never` if this `Subscriber` cannot receive errors.

    associatedtype Failure : Error


    /// Tells the subscriber that it has successfully subscribed to the publisher and may request items.

    ///

    /// Use the received ``Subscription`` to request items from the publisher.

    /// - Parameter subscription: A subscription that represents the connection between publisher and subscriber.

    func receive(subscription: Subscription)


    /// Tells the subscriber that the publisher has produced an element.

    ///

    /// - Parameter input: The published element.

    /// - Returns: A `Subscribers.Demand` instance indicating how many more elements the subscriber expects to receive.

    func receive(_ input: Self.Input) -> Subscribers.Demand


    /// Tells the subscriber that the publisher has completed publishing, either normally or with an error.

    ///

    /// - Parameter completion: A ``Subscribers/Completion`` case indicating whether publishing completed normally or with an error.

    func receive(completion: Subscribers.Completion<Self.Failure>)

}

 

我们仔细分析上边的代码,同样会得到以下几个重要信息:

 

  • Subscriber实现了CustomCombineIdentifierConvertible协议,用于标记唯一身份

  • Subscriber同样是一个协议

  • Subscriber/receive(subscription:)该方法由Subscriber实现,但是由Publisher来调用,Publisher调用了该方法后会传递一个实现了Subscription协议的实例,Subscriber使用该实例发送request请求数据

  • Subscriber实现了Subscriber/receive(_:)协议,Publisher调用该方法发送数据

  • Subscriber实现了Subscriber/receive(completion:)协议,Publisher调用该方法发送结束事件(.finished.failure)

  • Subscriber只接收输入数据

 

****在真实的开发中,我们用到最多的Subscriberassignsink

 

Operator


常用的Operator

 


["scan", "tryScan", "map/tryMap", "flatMap","setFailureType", 

 "compactMap/tryCompactMap", "filter/tryFilter", "removeDuplicates",

"replace", "collect", "ignoreOutput", "reduce","max", "min", "count", 

 "first", "last", "drop", "prepend", "dropFirst", "prefix", "output", 

 "combineLatest","merge", "zip", "allSatisfy", "contains", "catch", 

 "assertNoFailure", "retry", "mapError", "switchToLatest", "debounce", 

 "delay", "measureInterval", "throttle", "timeout", "encode", "decode",

 "share", "multicast","breakpoint", "breakpointOnError", "handleEvents", 

 "print", "receive", "subscribe"]

 

在Combine中,Operator是函数:

 


extension Publishers {


    /// A publisher that transforms all elements from the upstream publisher with a provided closure.

    public struct Map<Upstream, Output> : Publisher where Upstream : Publisher {


        /// The kind of errors this publisher might publish.

        ///

        /// Use `Never` if this `Publisher` does not publish errors.

        public typealias Failure = Upstream.Failure


        /// The publisher from which this publisher receives elements.

        public let upstream: Upstream


        /// The closure that transforms elements from the upstream publisher.

        public let transform: (Upstream.Output) -> Output


        public init(upstream: Upstream, transform: @escaping (Upstream.Output) -> Output)


        /// Attaches the specified subscriber to this publisher.

        ///

        /// Implementations of ``Publisher`` must implement this method.

        ///

        /// The provided implementation of ``Publisher/subscribe(_:)-4u8kn``calls this method.

        ///

        /// - Parameter subscriber: The subscriber to attach to this ``Publisher``, after which it can receive values.

        public func receive<S>(subscriber: S) where Output == S.Input, S : Subscriber, Upstream.Failure == S.Failure

    }

}

 

从上边的代码中,我们分析出以下几个重要信息:

 

  • 结构体Map实现了Publisher协议,因此它本身就是一个Publisher

  • init(upstream: Upstream, transform: @escaping (Upstream.Output) -> Output)从它的初始化化函数来看,它需要传入一个upstream: Upstream,这个upstream就是一个Publisher,还需要传入一个闭包,闭包的参数是上游publisher的输出数据

 

Map接收一个Publisher作为输入,然后等待该publisher输出数据,然后把该数据映射成其他数据类型。

 

Subscription


 

Subscription也是一个不容忽视的概念,是它连接了PublisherSubscriber,我们看看它的代码:

 


public protocol Subscription : Cancellable, CustomCombineIdentifierConvertible {


    /// Tells a publisher that it may send more values to the subscriber.

    func request(_ demand: Subscribers.Demand)

}

 

同样,基于上边的代码,我们分析出以下几个信息:

 

  • 它是一个协议,实现该协议的实例必须实现协议要求的方法

  • 它继承了Cancellable协议,因此实现了Subscription协议的实例自然就可以取消pipline

  • 使用request函数发送请求

 

事件过程


  1. Publisher收到订阅

  2. Publisher调用SubscriberSubscriber/receive(subscription:)方法返回一个subscription实例

  3. Subscriber使用subscription发送request

  4. Publisher调用SubscriberSubscriber/receive(_:)方法发送数据

  5. Publisher调用SubscriberSubscriber/receive(completion:)方法发送完成事件

Made with in Shangrao,China By 老雷

Copyright © devler.cn 1987 - Present

赣ICP备19009883号-1