Hello! I was playing around with Combine's scheduler and trying achieving a goal that some task is done and published in a background queue in upstream and the event is received in the main queue in downstream.
final class ObservableValue {
private var valueSubject: PassthroughSubject<Int, Never> = .init()
private let queue: DispatchQueue = .init(label: "com.observablevalue.queue")
var publisher: AnyPublisher<Int, Never> {
return valueSubject.eraseToAnyPublisher()
}
func set(_ value: Int) {
queue.async { [weak self] in
guard let self = self else {
return
}
// Suppose we do some long-running processing task in this background queue here before publishing the new value
self.valueSubject.send(value)
}
}
}
let value = ObservableValue()
let cancellable1 = value
.publisher
.sink { receiveValue in
print("cancellable1 received \(receiveValue) on main thread? \(Thread.current.isMainThread)")
}
let cancellable2 = value
.publisher
.receive(on: DispatchQueue.main)
.sink { receiveValue in
print("cancellable2 received \(receiveValue) on main thread? \(Thread.current.isMainThread)")
}
let cancellable3 = value
.publisher
.subscribe(on: DispatchQueue.main)
.sink { receiveValue in
print("cancellable3 received \(receiveValue) on main thread? \(Thread.current.isMainThread)")
}
value.set(1)
value.set(2)
In the example code above, only cancellable1
received the emitted value as expected in sink
, both cancellable2
and cancellable3
don't receive anything. Why? Then in this case, what should I do to make the value received from main queue in downstream? Thanks a lot!
Update: I just tried changing main queue in cancellable2
and cancellable3
to a customized background serial queue, and IT WORKS...curious why it just doesn't work for switching to main queue