gh-123152: Add a Concurrency Howto Page by ericsnowcurrently · Pull Request #123163 · python/cpython
I always mention "determinism" as one of my favourite assets of async in comparison with threading. The following sentences are not to explain this to you, but what I use to explain to people learning about this, maybe some of this can be incorporated here or in other part.
So...
In contrast with threading, where "something" (Python, the OS, the CPU) can take you out from the processor, in asyncio as it's a collaborative model you always have to yield it. Of course, you need to be sure to not be too greedy about it, but also means that the code you read sequentially, it happens sequentially.
In other words, if you have a logger call in line 5 and other logger call in line 27, when you're trying to debug what happened to a run of your program, and you check a log file, as you see the corresponding log line to logger call in code line 5, and the you see the corresponding log line to logger call in code line 27, you are sure that nothing got in the middle. This way, you can think of that part of the code sequentially, nothing changed any state, no objects values where modified, nobody messed with your system between those lines. And that is a HUGE difference with threading model, where you read those lines of code and you know that unless somehing is wrapped in a lock, a million things could have happened between line N and line N+1.