async/await

张开发
2026/4/4 0:20:13 15 分钟阅读
async/await
在 Python 里聊 async/await其实有点像聊怎么在一条单行道上安排多辆车同时出发但又不堵车。很多人刚接触时会觉得这不就是多线程吗其实不太一样。多线程是系统给你安排多个车道每个车道跑一辆车但 Python 里的线程因为 GIL 的存在很多时候是“假并行”更像是一个调度员快速切换车道上的车让它们轮流跑。而 async/await 更像是一条车道但每辆车都知道自己什么时候该让一下好让别的车先走一段。举个例子假设你在写一个网络爬虫要请求十个不同的网站。如果用传统同步的方式代码会依次发起请求等第一个网站返回数据了再去请求第二个这期间你的程序大部分时间在“空等”就像在收费站排队前面车付钱时后面只能干等。如果用 async/await发起第一个请求后不用等它回来就可以立刻发起第二个、第三个……等到某个请求的数据回来了再回来处理它。这就像在同一个窗口同时交十份材料每份材料处理需要时间但处理员在等的间隙可以处理另一份而不是傻等。但要注意async/await 并不会让代码自己变快它只是让你在“等待 IO”的时候能做别的事。如果你的任务全是计算密集型的比如算圆周率那用它反而可能增加复杂度效果也不明显。在语法上async 放在函数定义前意思是这个函数可以暂停和恢复await 放在需要等待的操作前意思是“这里可能要等先让其他任务跑吧”。不过真正用好 async/await 需要理解事件循环event loop—— 你可以把它想象成一个总调度员负责在多个任务之间切换哪个任务等的东西到了就让它继续执行。很多人容易掉进一个坑在 async 函数里调用了阻塞的同步代码比如用了某个不支持异步的库结果整个事件循环就卡住了。所以一般会建议用了 async/await配套的库最好也是异步的比如 aiohttp 而不是 requests。还有一点异步代码的调试比同步代码麻烦一些因为执行顺序不那么直观。有时候打印日志会发现明明代码写的是 A 在 B 前面打印出来却是 B 先出现这就是因为任务切换导致的。总的来说async/await 是 Python 处理 IO 密集型任务的一把利器但它不是银弹。用之前先想清楚场景如果全是 CPU 计算可能多进程更合适如果是大量网络请求、文件读写这类“等待型”工作那异步会带来明显的效率提升。刚开始写可能会觉得绕写多了就会习惯这种“让路”式的编程思维。

更多文章