Some people ask, what exactly is synchronous and asynchronous programming in Python?
Synchronous and asynchronous programming is actually quite easy to understand. For example, when you go to a site to download videos, there are two scenarios that represent synchronous and asynchronous.
1. Click to download video A, wait for A to finish downloading, then click to download video B, and so on for all videos.
2. Click to download video A, regardless of whether it has finished downloading, then immediately click to download video B, with all download tasks proceeding simultaneously, and so on for all videos.
The first scenario is synchronous, where tasks are executed in a queue, and the next task only starts after the previous one is completed.
The second scenario is asynchronous, where you work while waiting, using the waiting time to handle other tasks, allowing multiple tasks to run concurrently.
If we disregard network speed and bandwidth, the efficiency of the first method is clearly lower than that of the second.

Next, let’s test this with Python code, starting with synchronous execution of download tasks.
# Test: Using synchronous code
import time
def dowload(name):
print(f"{name}开始下载")
time.sleep(2) # Simulate video download time
print(f"{name}下载完成")
begin = time.time()
dowload("视频A") # Must wait for A to finish downloading...
dowload("视频B") # ...before starting to download video B
end = time.time()
print("用时{}秒".format(end - begin))
The result is as follows, taking more than 4 seconds.
Because synchronous programming blocks, video A must finish downloading before video B can start downloading.
Next, we will use asynchronous programming to achieve the same task.
Note that in Python, using asynchronous programming requires the special syntax of async/await.
# Test: Using asynchronous code
import asyncio
import time
async def dowload(name):
print(f"{name}开始下载")
await asyncio.sleep(2) # Non-blocking wait
print(f"{name}下载完成")
async def main():
await asyncio.gather(
dowload("视频A"),
dowload("视频B")
)
begin = time.time()
asyncio.run(main())
end = time.time()
print("用时{}秒".format(end - begin))
The result is as follows, taking only more than 2 seconds.
Asynchronous programming does not wait for A to finish downloading; it directly downloads B, allowing both to proceed simultaneously without blocking.

Now it is easy to understand the principles and differences between synchronous and asynchronous programming. Synchronous is about queuing tasks, while asynchronous is not about doing many tasks at the same time, but rather flexibly allocating effort across multiple tasks without wasting time waiting.
So what are the use cases for synchronous and asynchronous programming?
Synchronous programming is suitable for tasks that strictly depend on execution order, such as order tasks (place order -> ship), transfer tasks (deduct -> credit), and CPU-intensive tasks like mathematical calculations and image processing.
Asynchronous programming is suitable for I/O-intensive and high-concurrency tasks, such as sending messages to users, web requests, file reading and writing, and file downloading and uploading. These tasks typically involve waiting time, and asynchronous programming can improve task execution efficiency.
Therefore, synchronous and asynchronous programming are suitable for different business scenarios, and there is no absolute right or wrong.
The table below compares some scenarios and cases for reference.

