为什么需要异步编程?
在现代 Web 开发中,I/O 密集型操作(如数据库查询、API 调用、文件读写)占据了大量的时间。传统的同步编程模式会让程序在等待 I/O 完成时白白浪费 CPU 时间。
Python 从 3.4 版本开始引入 asyncio 模块,并在 3.5 版本中加入了 async/await 语法,使得异步编程变得更加直观和优雅。
核心概念
协程(Coroutine)
协程是使用 async def 定义的函数。与普通函数不同,协程可以在执行过程中挂起,让出控制权给其他协程。
import asyncio
async def fetch_data(url):
print(f"开始获取 {url}")
await asyncio.sleep(1) # 模拟网络请求
print(f"完成获取 {url}")
return f"来自 {url} 的数据"
async def main():
tasks = [fetch_data(f"https://api.example.com/{i}") for i in range(3)]
results = await asyncio.gather(*tasks)
print(results)
asyncio.run(main())
事件循环(Event Loop)
事件循环是 asyncio 的核心,它负责调度和执行协程。你可以把它想象成一个不断运行的循环,检查哪些任务可以继续执行。
实际应用场景
在 FastAPI 中,你可以直接使用 async def 定义路由处理函数,框架会自动处理异步执行。对于数据库操作,推荐使用 SQLAlchemy 的异步扩展或 asyncpg。
注意事项
- 不要在协程中调用阻塞函数,这会阻塞整个事件循环
- 对于 CPU 密集型任务,使用
loop.run_in_executor()放入线程池执行 - 异步不是银弹——对于简单脚本,同步代码反而更易维护