商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Python异步编程中有哪些常见陷阱_总结await位置不对导致的性能坑

Python异步编程中有哪些常见陷阱_总结await位置不对导致的性能坑

  发布于2026-07-07 阅读(0)

扫一扫,手机访问

在异步编程中,await 放错位置是个常见的坑。它不会触发任何报错,但悄悄就把并发给废了——所有请求变成同步等待,性能优势荡然无存。处理过异步代码的开发者,基本都遇到过这种烦恼。

await 写在循环里导致串行执行

想并发请求 10 个 URL,却把 await 放在 for 循环内部,结果就是逐个等待,总耗时 ≈ 所有请求时间之和。这属于最典型的误用。

  • 错误写法:for url in urls: data = await fetch(url) → 每次都得等上一个完成,下一个才能出发
  • 正确的做法是先收集所有协程,再用 asyncio.gather() 统一并发等待:results = await asyncio.gather(*[fetch(u) for u in urls])
  • 注意:gather() 里传的是协程对象(fetch(u)),不是函数名(fetch)。搞混了会报 TypeError: an asyncio.Future, a coroutine or an awaitable is required

在非 async 函数里漏掉 await 或 asyncio.run()

这个陷阱在脚本顶层或 Flask/Django 视图中很常见——直接调用 async def 函数,比如写 result = my_coro(),它只返回一个 ,逻辑根本不执行。

  • 现象:程序“没反应”、打印出 、或者弹出 RuntimeWarning: coroutine 'xxx' was never awaited
  • 脚本顶层:必须用 asyncio.run(my_coro()) 驱动
  • 已运行事件循环的环境(如 FastAPI、Jupyter):只能 await my_coro(),用 asyncio.run() 会报 RuntimeError: asyncio.run() cannot be called from a running event loop
  • 同步函数里要调异步逻辑:用 asyncio.get_event_loop().run_until_complete(my_coro())(Python 3.7+),或封装进线程池(asyncio.to_thread()

await 了不该 await 的东西

比如对 CPU 密集型操作加 await,或误 await 一个普通函数、字符串、数字——这些都不是 awaitable,会直接报 TypeError

  • 典型错误:await time.sleep(1)time.sleep 是同步阻塞,且不是协程,不能 await;应换成 await asyncio.sleep(1)
  • 更隐蔽的:await requests.get(...)requests 是同步库,返回 Response 对象,不是协程;得换 aiohttphttpx.AsyncClient
  • 调试技巧:启用 asyncio 调试模式,asyncio.run(main(), debug=True),能捕获长时间阻塞并发出警告

最容易被忽略的是:await 本身不解决 CPU 瓶颈,它只释放 I/O 等待期间的控制权。如果协程里混着大循环、正则匹配、JSON 解析这类计算密集操作,整个事件循环会被卡住——这时候得用 loop.run_in_executor() 拆出去,而不是盲目加 await。

本文转载于:https://www.php.cn/faq/2426583.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注