Combine v.s. Async/Await

I am curious what’s the difference between Combine and Async/Await? And how could we work on both of them?

Combine is a Apple’s framework based on the reactive streams protocol. It offers a wide range of predefined “operators” which help you work with streams of values over time. Combine allows you to solve very complex problems, especially when you need to combine events and data over time from various sources.

The new concurrency model offers a lower-level APIs for executing asynchronous code — think that it should be replacing GCD in your app, not Combine. A combination of using tasks and async sequences could allow you handle simpler problems that you other would use Combine for.

In summary, the new concurrency APIs allow you to do more without Combine, but for complex apps you still might want to fallback on Combine. Interoperation is easy and the book includes a number of examples but the cornerstone is the Publisher.values API which allows you to asynchronously loop over a publisher.

One last benefit is that the new concurrency APIs are available on Linux while Combine isn’t.

6 Likes

Thanks for the detailed answer! @icanzilb
So, my understanding is it’s like GCD and OperationQueue, right?
Combine (OperationQueue) could do all things Async (GCD) can do. But Async (GCD) is much easier to use.

Right, the new concurrency APIs are here to replace (and obsolete) GCD and operations. Combine will stay because it’s a higher level, more complex framework.

2 Likes

@icanzilb, replaces BOTH of them, i mean GCD and Operation, right? because the Task with the priority initializer, it looks like the same old Operation queue, which it would create a new queue based on the given priority. then having one Task after another, they would be executed in a serialize manner, right? and then how about mutli-threading, like locking a thread and releasing it after the process is done?

@mohamad operations and tasks work differently. When I said it replaces GCD and operation I meant in respect to Combine, in the sense that Combine offers higher level operators (which tasks don’t). While GCD and operations “occupy” a thread, tasks don’t do that so the model is completely different.

It feels like Apple have given up on Combine, no updates at all for almost two years since the 2020 WWDC, and it’s not cross platform at all and being tightly coupled to SwiftUI, I find it’s use is not as broad as RxSwift, which can run on LINUX with Swift.

The new structured concurrency systems are easier to read, debug, write and are cross platform. For cross platform I have to use RxSwift anyway if I want bindings between systems.

1 Like

I believe thinking about what the new async/await APIs replace isn’t the way to go about this. The new approach to concurrency is different and thinking in the old patters could be counter-productive.

Task is a powerful API but it doesn’t work exactly as a dispatch work item or an operation.

Unlike operation queues you can’t “order” tasks in a group or a queue. To execute tasks in order you just await them, i.e. await myFunc1(); await myFunc2() etc.

Additionally, you are not supposed to block threads from asynchronous context. You await tasks to completion and then continue with the code you want to execute. I’d recommend generally avoiding completely using thread or dispatch APIs from async context — I found that mixing them together is counter-productive.

I agree to a point with what you’re saying. I would’ve loved if Combine got more attention from Apple — I’m a big fan of reactive code. However, with async/await being a feature built into the language, it’s a much more powerful tool for developer to use across platforms and regardless of the UI or storage frameworks in their current project. As the async/await functionality is still in flux, I’m sure there will be more complex APIs with AsyncSequence/AsyncSteam to reimplement some of the big benefits of Combine

1 Like