Hi, @Serendipity, I am also studying Combine recently, and I want to share some of my thoughts.
I’m working on CombineX currently in my spare time, which is an open source implementation of Combine. And you can see my implementation of ReceiveOn here.
Just as @mayoff said, the main reason for the problem is the following lines:
func receive(subscription: Subscription) {
guard self.lock.withLockGet(self.state.relay(subscription)) else {
subscription.cancel()
return
}
self.schedule { // the downstream will receive the subscription on scheduler
self.sub.receive(subscription: self)
}
}
So things become:
var subscribed = false
func send(_ output: Int) {
if subscribed {
print("send:", output)
}
}
runLoop.perform {
subscribed = true
}
send(1) // won't print "1" since subscribed is false now
An elegant way to solve your problem is a new operator: ReceiveValueOn, which only schedule input and completion event with the scheduler. We plan to add it to CXExtensions later, then you can take a look!
By the way! CombineX needs help very much now. If you are interested in Combine, you are welcome to join us, whether as a project manager, a developer or coder reviewer, we are all grateful! It is a great opportunity to validate and learn from Combine!