简体   繁体   English

什么是 PassthroughSubject 和 CurrentValueSubject

[英]What is PassthroughSubject & CurrentValueSubject

I happen to look into Apple's new Combine framework, where I see two things我碰巧研究了 Apple 新的 Combine 框架,在那里我看到了两件事

PassthroughSubject<String, Failure>

CurrentValueSubject<String, Failure>

Can someone explain to me what is meaning & use of them?有人可以向我解释它们的含义和用途吗?

I think we can make analogies with real world cases.我认为我们可以与现实世界的案例进行类比。

PassthroughSubject = A doorbell push button PassthroughSubject = 门铃按钮

When someone rings the door, you are notified only if you are at home (you are the subscriber)当有人敲门时,只有您在家时才会收到通知(您是订阅者)

PassthroughSubject doesn't have a state, it emits whatever it receives to its subscribers. PassthroughSubject 没有状态,它将接收到的任何内容发送给订阅者。

CurrentValueSubject = A light switch Someone turns on the lights in your home when you are outside. CurrentValueSubject = 电灯开关当您外出时,有人打开您家中的灯。 You get back home and you know someone has turned them on.你回到家,你知道有人打开了它们。

CurrentValueSubject has an initial state, it retains the data you put in as its state. CurrentValueSubject 有一个初始状态,它保留你放入的数据作为它的状态。

Both PassthroughSubject and CurrentValueSubject are publishers that conform to the Subject protocol which means you can call send on them to push new values downstream at will. PassthroughSubjectCurrentValueSubject都是符合Subject协议的发布者,这意味着您可以在它们上调用send以随意将新值推送到下游。

The main difference is that CurrentValueSubject has a sense of state (current value) and PassthroughSubject simply relays values directly to its subscribers without remembering the "current" value:主要区别在于CurrentValueSubject具有状态感(当前值),而PassthroughSubject只是将值直接传递给其订阅者,而不记住“当前”值:

var current = CurrentValueSubject<Int, Never>(10)
var passthrough = PassthroughSubject<Int, Never>()

current.send(1)
passthrough.send(1)

current.sink(receiveValue: { print($0) })
passthrough.sink(receiveValue: { print($0) })

You'd see that the current.sink is called immediately with 1 .您会看到current.sink立即用1调用。 The passthrough.sink is not called because it has no current value. passthrough.sink没有被调用,因为它没有当前值。 The sink will only be called for values that are emitted after you subscribe.只有在您订阅后发出的值才会调用接收器。

Note that you can also get and set the current value of a CurrentValueSubject using its value property:请注意,您还可以使用其value属性获取和设置CurrentValueSubject的当前值:

current.value // 1
current.value = 5 // equivalent to current.send(5)

This isn't possible for a passthrough subject.这对于直通主题是不可能的。

PassthroughSubject is used for representing events. PassthroughSubject用于表示事件。 Use it for events like button tap.将它用于按钮点击等事件。

CurrentValueSubject is used representing state. CurrentValueSubject用于表示状态。 Use it for storing any value, say state of switch as off and on.使用它来存储任何值,例如开关状态为关闭和打开。

Note: @Published is kind of CurrentValueSubject .注意: @PublishedCurrentValueSubject的一种。

PassthroughSubject and CurrentValueSubject are both Publisher s — a type introduced by Combine — that you can subscribe to (performing operations on values when values are available). PassthroughSubjectCurrentValueSubject都是Publisher —— 一种由 Combine 引入的类型——你可以订阅它们(当值可用时对值执行操作)。

They both are designed to make it easy to transfer to using the Combine paradigm.它们都旨在使转换为使用组合范式变得容易。 They both have a value and an error type, and you can "send" values to them (making the values available to all subscribers)它们都有一个值和一个错误类型,您可以向它们“发送”值(使所有订阅者都可以使用这些值)

The main difference between the two that I've seen is that CurrentValueSubject starts with a value, while PassthroughSubject does not.我看到的两者之间的主要区别是CurrentValueSubject以一个值开头,而PassthroughSubject不是。 PassthroughSubject seems easier to grasp conceptually, at least for me. PassthroughSubject在概念上似乎更容易掌握,至少对我来说是这样。

PassthroughSubject can easily be used in place of a delegate pattern, or to convert an existing delegate pattern to Combine. PassthroughSubject可以很容易地用来代替委托模式,或者将现有的委托模式转换为组合。

//Replacing the delegate pattern
class MyType {
    let publisher: PassthroughSubject<String, Never> = PassthroughSubject()

    func doSomething() {
        //do whatever this class does

        //instead of this:
        //self.delegate?.handleValue(value)

        //do this:
        publisher.send(value)
    }
}

//Converting delegate pattern to Combine
class MyDel: SomeTypeDelegate {
    let publisher: PassthroughSubject<String, Never> = PassthroughSubject()

    func handle(_ value: String) {
        publisher.send(value)
    }
}

Both of these examples use String as the type of the value, while it could be anything.这两个示例都使用String作为值的类型,而它可以是任何值。

Hope this helps!希望这可以帮助!

PassthroughSubject is suitable for event like tap action PassthroughSubject适用于像点击动作这样的事件

CurrentValueSubject is suitable for state CurrentValueSubject适用于状态

Already a lot of good answers posted in this thread, just thought of adding this answer for someone who is coming from using RxSwift.在这个线程中已经发布了很多好的答案,只是想为使用 RxSwift 的人添加这个答案。

PassThroughSubject is like PublishSubject where it broadcasts an event to its subscribers, probably with some value passed along. PassThroughSubject就像PublishSubject一样,它向订阅者广播一个事件,可能带有一些传递的值。

CurrentValueSubject is similar to BehaviorRelay where a single value is persisted with the subject instance and passed along during the event broadcast. CurrentValueSubject类似于BehaviorRelay ,其中单个值与主题实例一起持久保存并在事件广播期间传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM