Github.com/agelessman/…

As is known to all, Combine aims to solve the problem of how data flows asynchronously, which inevitably involves the discussion of threads and scheduling. In which thread is data processed? In which thread does it flow out?

receive

If you look closely at the figure above, you can see that receive can change the thread that receives its downstream data. Note that it affects the downstream.

This is useful in situations where, for example, when we make a network request, we want it to be invoked in the child thread, and when the data comes back, we want to refresh the UI in the main thread.

Here’s an example:

cancellable = publisher
    .sink(receiveCompletion: {
        DispatchQueue.main.async {
            / / / refresh the UI
        }
    }, receiveValue: {
        print($0)})Copy the code
cancellable = publisher
    .receive(on: RunLoop.main)
    .sink(receiveCompletion: {
        / / / refresh the UI
    }, receiveValue: {
        print($0)})Copy the code

As you can see from the comparison above, when threads are switched using receive, downstream data and processing are switched to the thread specified by receive.

subscribe

Subscribe, as opposed to receive, affects the thread that calls the pipline upstream. Since subscribe is not used very much in real development, we won’t explain it in detail,

let publisher = PassthroughSubject<Int.Error> ()let myBgQueue = DispatchQueue(label: "myBgQueue")

cancellable = publisher
    .subscribe(on: myBgQueue)
    .receive(on: RunLoop.main)
    .sink(receiveCompletion: {
        print($0)
        / / / refresh the UI
    }, receiveValue: {
        print($0)
    })

publisher.send(1)
Copy the code