Flask 2.0 原生支持异步视图函数,但必须使用 ASGI 服务器(如 Uvicorn)启动才能真正实现非阻塞并发,直接使用 flask run 会导致异步代码退化为同步执行或报错。
先说结论:Flask 2.0 允许使用 async def 定义视图,但只有在 ASGI 模式下才能发挥异步 IO 优势,WSGI 模式下无法获得并发性能提升。
- 适合场景:高并发 IO 密集型任务,如同时请求多个外部 API 或数据库查询。
- 先准备:安装 flask[async] 扩展包,并部署 Uvicorn 或 Hypercorn 等 ASGI 服务器。
- 再验证:启动日志显示 ASGI 协议信息,且异步视图内 await 操作不阻塞其他请求。
命令速用版
安装支持异步的 Flask 扩展包并使用 Uvicorn 启动应用,不要使用 flask run 命令。
pip install \"flask[async]\"\nuvicorn main:app `--reload`
确保 main.py 中不包含 if __name__ == '__main__': app.run() 这类 WSGI 启动逻辑,否则会绕过 ASGI 检查。
为什么会这样
Flask 2.0 的异步支持依赖底层服务器是否运行在 asyncio 事件循环中。传统 WSGI 服务器(如 Werkzeug 开发服务器)为每个请求分配独立线程,async def 视图在其中会被当作同步函数处理,await 表达式无法挂起当前线程去处理其他请求。只有 ASGI 服务器(如 Uvicorn)才能在单线程事件循环中调度协程,实现 IO 等待期间切换任务。
分步处理
第一步安装依赖,执行 pip install \"flask[async]\" 确保 Flask 包含异步支持组件。
第二步编写异步视图,使用 async def 定义路由函数,并在 IO 操作前添加 await,例如 await asyncio.sleep(1) 或 await httpx.AsyncClient().get()。
第三步更换启动方式,使用 uvicorn main:app 命令启动,避免使用 flask run 或 app.run()。
第四步检查兼容性,确保视图内调用的第三方库是异步版本(如 asyncpg、aiohttp),禁止混用 requests 或 time.sleep 等阻塞调用。
怎么验证是否生效
查看终端启动日志,确认出现 ASGI 'http' protocol 字样,若显示 WSGI 则说明未进入异步模式。
并发测试多个请求,观察异步视图在执行 await 等待时,服务器是否能同时响应其他请求,而不会像同步视图那样排队阻塞。
检查错误日志,若出现 RuntimeError: There is no current event loop 或 Async views require Werkzeug >= 2.0,说明服务器配置不正确。
常见坑
误区一:认为写了 async def 就自动变快,若在异步视图中调用 requests.get() 等同步库,整个事件循环仍会被阻塞。
误区二:使用 flask run 启动,该命令默认使用 WSGI 模式,异步视图会被降级为同步执行,无法利用协程特性。
误区三:在视图内使用 asyncio.create_task 派生后台任务,WSGI 模式下请求结束后事件循环会停止,导致后台任务被取消,需使用任务队列或 ASGI 适配器。
常见问题
Flask 2.0 写 async def 报错 no running event loop 怎么办
这是因为使用了 WSGI 服务器启动,请改用 uvicorn 或 hypercorn 等 ASGI 服务器运行应用。
异步视图里能直接用 requests 库请求接口吗
不能,requests 是同步库会阻塞事件循环,必须替换为 httpx 或 aiohttp 等异步 HTTP 客户端。
Flask 异步视图能提升 CPU 计算性能吗
不能,异步主要用于优化 IO 等待期间的并发能力,CPU 密集型任务仍需多进程或多线程处理。
参考来源
- Flask Documentation (3.0.x) - 使用 async 和 await
- 如何对比 Flask 2.x 与 Flask 3.x 的性能差异_分析异步视图 async 支持
- Flask 2.x 怎么兼容原生异步 IO 库_Python 基于 async/await 改造高并发视图函数
- Python Flask 怎么写异步_Flask2.0 新特性结合 asyncio 生态原生实现高并发异步视图处理
- 新特性 - Flask 2.0 基本的 async/await 支持