debug: multicast triggered..
只打印一次。既然苹果说
multicast(_:)
为每个订阅者创建一个新的发布者,那么打印语句不应该被触发两次吗?
import Foundation
import Combine
var cancellables = Set<AnyCancellable>()
let upstreamPublisher = Range(1...3).publisher.delay(for: 1, scheduler: DispatchQueue.main)
let sharedSubject = CurrentValueSubject<Int, Never>(-1)
// Create a multicast publisher and apply autoconnect
let multicastPublisher = upstreamPublisher
.multicast({
print("debug: multicast triggered..")
return sharedSubject
})
.autoconnect()
// Subscriber 1
multicastPublisher
.sink { value in
print("Subscriber 1 received value: \(value)")
}
.store(in: &cancellables)
// Subscriber 2
multicastPublisher
.sink { value in
print("Subscriber 2 received value: \(value)")
}
.store(in: &cancellables)
// Output
//debug: multicast triggered..
//Subscriber 1 received value: -1
//Subscriber 2 received value: -1
//Subscriber 1 received value: 1
//Subscriber 2 received value: 1
//Subscriber 1 received value: 2
//Subscriber 2 received value: 2
//Subscriber 1 received value: 3
//Subscriber 2 received value: 3
multicast(_:)
似乎只调用其闭包一次,而不是在每个订阅者附加到它时重复调用。 (“每次订阅者附加到多播发布者时创建一个新的
Subject
”的表面概念似乎完全违背了多播的目的,即您只需要对发布者的
receive<S>(subscriber:)
方法进行一次调用。)在我看来,这看起来像是和
multicast(_:)
之间的区别似乎很简单,前者采用Subject
,而后者采用闭包返回
Subject
。
var cancellables = Set<AnyCancellable>()
let upstreamPublisher = (1...3).publisher
.map { _ in Int.random(in: 0...100) }
// Create a multicast publisher
let multicastPublisher = upstreamPublisher
.multicast {
print("debug: multicast triggered…")
return PassthroughSubject<Int, Never>()
}
// Subscriber 1
multicastPublisher
.sink { value in
print("Subscriber 1 received value: \(value)")
}
.store(in: &cancellables)
// Subscriber 2
multicastPublisher
.sink { value in
print("Subscriber 2 received value: \(value)")
}
.store(in: &cancellables)
// Connect
multicastPublisher.connect()
.store(in: &cancellables)
这需要对原始代码片段进行一些修改:
connect()
,直到添加了所有订阅者。
multicast
函数返回“可连接”发布者的要点是,您可以将连接推迟到代码中的某个未来点。因为我现在推迟了
connect()
,所以我可以删除
delay
,这只是为了防止第一个订阅者在第二个订阅者到达之前耗尽序列所必需的。 (显然,如果您愿意,您可以将
delay
添加回来:我的观点只是,如果您推迟
connect()
,则不需要
delay
。)
map
,因为这可以更好地说明多播的实用性(其中每个订阅者接收相同的值;如果您使用
multicast
删除此再现中的
map
,则每个订阅者将获得不同系列的随机值)。
PassThroughSubject
,以避免任意哨兵值,但如果您的场景需要的话,显然可以使用
CurrentValueSubject
。
debug: multicast triggered…
Subscriber 2 received value: 96
Subscriber 1 received value: 96
Subscriber 2 received value: 32
Subscriber 1 received value: 32
Subscriber 2 received value: 57
Subscriber 1 received value: 57