Switch schedulers?

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

Terms of Service

Privacy Policy

Cookie Policy