Flask 2.x 的 async 视图仅在 ASGI 服务器(如 Uvicorn)下有效,WSGI 模式不支持异步;需用 uvicorn 启动、使用异步库、避免阻塞调用,并确保中间件与扩展兼容 async。

Flask 2.x 原生支持 async 视图,但不等于自动支持 asyncio 库的任意异步 IO
Flask 2.0+ 确实允许你写 async def 视图函数,但它的底层 WSGI 适配器(比如 Werkzeug 的开发服务器)**根本不运行在 asyncio event loop 中**。直接在 async 视图里调用 asyncio.sleep()、aiohttp.ClientSession() 或 aiomysql.connect() 会报 RuntimeError: no running event loop —— 因为 Flask 默认没帮你启动 loop,更没把请求生命周期绑定到它上面。
真正能跑通原生异步 IO 的前提是:Web 服务器本身是 ASGI 兼容的(如 Uvicorn、Hypercorn),且你用的是 ASGI 模式启动 Flask(不是 flask run 默认的 WSGI 模式)。
必须用 ASGI 服务器启动,否则 async 视图只是“语法合法,运行报错”
Flask 2.x 的 async 视图只在 ASGI 模式下被正确调度。WSGI 模式下即使你写了 async def,Werkzeug 也会把它当同步函数处理,await 表达式根本不会执行,或者直接抛出 RuntimeError。
- 启动命令必须换成:
uvicorn myapp:app --reload(假设app是 Flask 实例) - 确保安装了
uvicorn(或hypercorn),且版本 ≥ 0.13.0(对 Flask ASGI 支持较稳) -
myapp.py中不能有if __name__ == '__main__': app.run()这类 WSGI 启动逻辑,否则会绕过 ASGI - 检查日志:启动时看到
ASGI 'http' protocol on http://127.0.0.1:8000才算走对路
async 视图里调用原生异步库,要确认它们运行在同一个 event loop 上
Uvicorn 启动后,每个请求会在主线程的同一个 asyncio event loop 中调度。但如果你在视图里手动调用 asyncio.get_event_loop() 或新建 asyncio.new_event_loop(),就可能出问题 —— 尤其在多 worker 场景下,loop 可能未运行、已被关闭,或和 Uvicorn 管理的 loop 不一致。
立即学习“Python免费学习笔记(深入)”;
- 直接 await 标准异步库即可,例如:
await aiofiles.open(...)、await httpx.AsyncClient().get(...) - 避免显式调用
asyncio.run():它会强制创建新 loop,与当前请求 loop 冲突 - 数据库驱动必须用纯异步版:如
asyncpg(PostgreSQL)、aiomysql(MySQL)、motor(MongoDB);SQLAlchemy 1.4+的create_async_engine()也行,但 ORM 查询需用await session.execute()而非.all() - 注意:
time.sleep()和requests.get()这类阻塞调用仍会卡住整个 event loop,必须换为asyncio.sleep()和httpx.AsyncClient()
别忽略中间件、扩展和错误处理器的 async 兼容性
async 视图生效后,整个请求链路上所有环节都得支持协程。Flask 自带的 @app.errorhandler、@app.before_request 如果是同步函数,Uvicorn 会等它返回再进视图;但如果里面用了 await 却没声明为 async,就会报 SyntaxError 或静默失败。
- 自定义错误处理器必须写成:
@app.errorhandler(500) async def handle_500(e): ... - 使用 Flask-Login、Flask-SQLAlchemy 等扩展前,查清是否发布 async 版本(例如 Flask-SQLAlchemy 3.x 开始支持 async engine,但 2.x 完全不兼容)
- 日志记录尽量避免阻塞操作;如果必须写文件,用
aiofiles替代内置open() - 调试时加一句
print(asyncio.get_running_loop())在视图开头,确认没意外切换 loop
最常被忽略的一点:开发时用 uvicorn 跑通了,上线却用 Gunicorn + WSGI worker 启动,async 视图瞬间退化为同步行为,甚至 crash。部署配置比代码更关键。


















