news 2026/6/10 17:27:10

async 和 await

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
async 和 await

现代版本的 Python 有一种非常直观的方式来定义异步代码。这使它看起来就像正常的"顺序"代码,并在适当的时候"等待"。

当有一个操作需要等待才能给出结果,且支持这个新的 Python 特性时,你可以编写如下代码:

burgers = await get_burgers(2)

这里的关键是await。它告诉 Python 它必须等待get_burgers(2)完成它的工作 ,然后将结果存储在burgers中。这样,Python 就会知道此时它可以去做其他事情 (比如接收另一个请求)。

要使await工作,它必须位于支持这种异步机制的函数内。因此,只需使用async def声明它:

async def get_burgers(number: int): # Do some asynchronous stuff to create the burgers return burgers

...而不是def:

# This is not asynchronous def get_sequential_burgers(number: int): # Do some sequential stuff to create the burgers return burgers

使用async def,Python 就知道在该函数中,它将遇上await,并且它可以"暂停" 执行该函数,直至执行其他操作 后回来。

当你想调用一个async def函数时,你必须"等待"它。因此,这不会起作用:

# This won't work, because get_burgers was defined with: async def burgers = get_burgers(2)

因此,如果你使用的库告诉你可以使用await调用它,则需要使用async def创建路径操作函数 ,如:

@app.get('/burgers') async def read_burgers(): burgers = await get_burgers(2) return burgers

更多技术细节

你可能已经注意到,await只能在async def定义的函数内部使用。

但与此同时,必须"等待"通过async def定义的函数。因此,带async def的函数也只能在async def定义的函数内部调用。

那么,这关于先有鸡还是先有蛋的问题,如何调用第一个async函数?

如果你使用FastAPI,你不必担心这一点,因为"第一个"函数将是你的路径操作函数,FastAPI 将知道如何做正确的事情。

但如果你想在没有 FastAPI 的情况下使用async/await,则可以这样做。

编写自己的异步代码

Starlette (和FastAPI) 是基于 AnyIO 实现的,这使得它们可以兼容 Python 的标准库 asyncio 和 Trio。

特别是,你可以直接使用 AnyIO 来处理高级的并发用例,这些用例需要在自己的代码中使用更高级的模式。

即使你没有使用FastAPI,你也可以使用 AnyIO 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如, 结构化并发)。

我(指原作者 —— 译者注)基于 AnyIO 新建了一个库,作为一个轻量级的封装层,用来优化类型注解,同时提供了更好的自动补全内联错误提示等功能。这个库还附带了一个友好的入门指南和教程,能帮助你理解并编写自己的异步代码:Asyncer。如果你有结合使用异步代码和常规(阻塞/同步)代码的需求,这个库会特别有用。

其他形式的异步代码

这种使用asyncawait的风格在语言中相对较新。

但它使处理异步代码变得容易很多。

这种相同的语法(或几乎相同)最近也包含在现代版本的 JavaScript 中(在浏览器和 NodeJS 中)。

但在此之前,处理异步代码非常复杂和困难。

在以前版本的 Python,你可以使用多线程或者 Gevent。但代码的理解、调试和思考都要复杂许多。

在以前版本的 NodeJS / 浏览器 JavaScript 中,你会使用"回调",因此也可能导致“回调地狱”。

协程

协程只是async def函数返回的一个非常奇特的东西的称呼。Python 知道它有点像一个函数,它可以启动,也会在某个时刻结束,而且它可能会在内部暂停 ⏸ ,只要内部有一个await

通过使用asyncawait的异步代码的所有功能大多数被概括为"协程"。它可以与 Go 的主要关键特性 "Goroutines" 相媲美。

结论

让我们再来回顾下上文所说的:

Python 的现代版本可以通过使用asyncawait语法创建协程,并用于支持异步代码

现在应该能明白其含义了。

所有这些使得 FastAPI(通过 Starlette)如此强大,也是它拥有如此令人印象深刻的性能的原因。

路径操作函数

当你使用def而不是async def来声明一个路径操作函数时,它运行在外部的线程池中并等待其结果,而不是直接调用(因为它会阻塞服务器)。

如果你使用过另一个不以上述方式工作的异步框架,并且你习惯于用普通的def定义普通的仅计算路径操作函数,以获得微小的性能增益(大约100纳秒),请注意,在 FastAPI 中,效果将完全相反。在这些情况下,最好使用async def,除非路径操作函数内使用执行阻塞 I/O 的代码。

在这两种情况下,与你之前的框架相比,FastAPI可能仍然很快。

依赖

这同样适用于依赖。如果一个依赖是标准的def函数而不是async def,它将被运行在外部线程池中。

子依赖

你可以拥有多个相互依赖的依赖以及子依赖 (作为函数的参数),它们中的一些可能是通过async def声明,也可能是通过def声明。它们仍然可以正常工作,这些通过def声明的函数将会在外部线程中调用(来自线程池),而不是"被等待"。

其他函数

你可直接调用通过defasync def创建的任何其他函数,FastAPI 不会影响你调用它们的方式。

这与 FastAPI 为你调用路径操作函数和依赖项的逻辑相反。

如果你的函数是通过def声明的,它将被直接调用(在代码中编写的地方),而不会在线程池中,如果这个函数通过async def声明,当在代码中调用时,你就应该使用await等待函数的结果。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 13:43:24

终极解放双手!M9A重返未来:1999自动化助手完整攻略

终极解放双手!M9A重返未来:1999自动化助手完整攻略 【免费下载链接】M9A 重返未来:1999 小助手 项目地址: https://gitcode.com/gh_mirrors/m9a/M9A 还在为《重返未来:1999》中重复的日常任务而烦恼吗?M9A这款专…

作者头像 李华
网站建设 2026/6/9 16:51:20

2026年Java开发者AI大模型转型指南:6个月学习路线,轻松跨界成功!

随着AI大模型技术的迅猛发展,传统Java开发者正面临前所未有的职业转型机遇。据LinkedIn报告显示,AI相关岗位增长率高达74%,而兼具传统开发经验和AI技能的复合型人才尤为稀缺。本文将为拥有多年Java开发经验的程序员提供一份从基础到精通的AI大…

作者头像 李华
网站建设 2026/6/9 22:19:08

Java力扣---滑动窗口(2)

209. 长度最小的子数组 - 力扣(LeetCode) 分析:这个题目是在滑动窗口题目的类似题目中的,所以最开始就是准备用滑动窗口来做的 这里用到了滑动窗口的先进先出,但是要用数字和sum做更新,所以我想到了队列&a…

作者头像 李华
网站建设 2026/6/10 10:20:06

超实用的“财务数据统计报表-可视化图表”Excel模板分享!

超实用的“财务数据统计报表-可视化图表”Excel模板分享! 作为财务工作者或数据分析师,您是否还在为每月制作复杂的财务报表而头疼?手动的录入、计算和图表制作,不仅耗费时间,还容易出错。 📥 模板下载地…

作者头像 李华
网站建设 2026/6/10 7:40:29

SillyTavern终极配置指南:10个技巧让你的AI聊天体验翻倍升级

SillyTavern终极配置指南:10个技巧让你的AI聊天体验翻倍升级 【免费下载链接】SillyTavern LLM Frontend for Power Users. 项目地址: https://gitcode.com/GitHub_Trending/si/SillyTavern 还在为AI聊天界面的单调乏味而苦恼吗?想要打造一个既美…

作者头像 李华
网站建设 2026/6/10 14:10:56

免费终极PDF对比神器:diff-pdf让文档差异一目了然

免费终极PDF对比神器:diff-pdf让文档差异一目了然 【免费下载链接】diff-pdf A simple tool for visually comparing two PDF files 项目地址: https://gitcode.com/gh_mirrors/di/diff-pdf 在日常工作和学习中,PDF文档对比是每个人都会遇到的难题…

作者头像 李华