Combine(一) Publisher和Subscriber

1、Publisher被观察者

Publisher是一个protocol,是Combine的核心;publisher可以向他的subscriber发送一个或多个values直到它发送了一个completion时间,这个completion可以是正常的结束,也可以是一个error。我们可以很简单的用一个array来创建一个publisher:

let publisher = (1...5).publisher // b
publisher.sink(receiveCompletion: { _ in // a
    print("completed")
}, receiveValue: { val in
    print("value: \(val)")
})
// 输出
value: 1
value: 2
value: 3
value: 4
value: 5
completed

a) .sink和.assign是两个为publisher绑定观察者的方法,观察者就像例子中的一样,是简单的closures来handle publisher发送出的值和结束事件。
b) 用array创建出的publisher会将array中的元素一个一个的发送给观察者然后结束。注意:publisher只有在有观察者的情况下才会开始发送value

而在上一篇文章中的Just就是一个特殊的Publisher,他只会发送一次然后自动结束

let just = Just("Hello shit")
just.sink(receiveCompletion: {
    _ in
    print("completed 111")
}, receiveValue: {
    val in
    print("\(val) 111")
})

just.sink(receiveCompletion: {
    _ in
    print("completed222")
}, receiveValue: {
    val in
    print("\(val) 222")
})
// 输出
Hello shit 111
completed 111
Hello shit 222
completed222

2、Subject

Subject也可以理解成特殊的Publisher,不同于publisher,subject可以用.send()来想subscriber发送values。先介绍两种常用的subjects:

  • PassthroughSubject - 可以持续向subscriber传输值或者结束事件,可以没有初始值
  • CurrentValueSubject - 初始化时必须有初始值,可以通过subject.value来查看当前publisher发送的值

看完Subscriber一起给栗子

3、Subscriber观察者

上面的两个例子都是用了sink绑定了closures来作为观察者, 如果我们要自己定义subscriber,那就得遵循Subscriber protocol:

class MySubscriber: Subscriber {
    typealias Input = Int // a
    typealias Failure = MyError // b

    func receive(completion: Subscribers.Completion) { // c
        print("received completion")
    }

    func receive(_ input: Int) -> Subscribers.Demand { // d
        print("received value: \(input)")
        switch input {
        case 1:
            return .max(1) // e
        default:
            return .none // f
        }
    }

    func receive(subscription: Subscription) { // g
        subscription.request(.max(2)) // h
        print("subscription received")
    }
}

a) 接受的类型,这个必须和publisher的输出类型相等才行
b) 错误类型,也需要和publisher会发出的error类型一样
c) 当接收到publisher发出的结束事件之后要做的
d) 当接收到publisher发出的值的时候要做的,注意这里返回了一个Subscribers.Demand意思是最多还能接受多少个values
e) 把最多能接受values的个数+1
f) 最多能接受values的个数不变
g) 当订阅了publisher的时候执行,subscription.request可以定义初始接受values的个数

let publisher = PassthroughSubject()
let subscriber = MySubscriber()
publisher.subscribe(subscriber)

publisher.send(3)
publisher.send(1)
publisher.send(5)
publisher.send(6)
publisher.send(completion: .finished)
//输出
subscription received
received value: 3
received value: 1
received value: 5
received completion

为啥没输出6呢?回去看看MySubscriber的定义就明白了

你可能感兴趣的:(Combine(一) Publisher和Subscriber)