Future 类
asyncio.Future 是异步编程里的核心概念:代表一个异步操作的最终结果,本质上是一个**「结果占位符」**。
可以把它理解成异步世界里的**「欠条」**------现在还没结果,但将来某个时刻会有。
一句话:Future 就是一张**「取餐号」**:你拿到它时结果还没有,但你可以 await 它,等结果好了自动拿到。
用生活场景理解
想象你去奶茶店点了一杯奶茶:
- 付完钱,店员给你一个取餐号(这就是 Future)
- 奶茶还没做好,但你知道「迟早会做好」
- 你可以选择:
- 等着 (
await future)------ 站在柜台前等,做好了直接拿走 - 先干别的 (
add_done_callback)------ 去逛街,做好了店员打电话通知你
- 等着 (
这个「取餐号」就是 Future 的本质------一个将来才会有结果的承诺。
最简单的例子
python
import asyncio
async def main():
# 1. 创建一张"欠条"
future = asyncio.get_running_loop().create_future()
# 2. 1秒后把结果填上去
asyncio.get_running_loop().call_later(1, future.set_result, "奶茶好了!")
# 3. 等着拿结果
result = await future
print(result) # 输出: 奶茶好了!
asyncio.run(main())
整个过程就是:
- 创建一张空白的「欠条」(Future)
- 某个时刻,有人把结果写上去(
set_result) await就是「等结果写好再往下走」
那它到底有什么用?
最典型的场景:你在写一个库,需要让调用者等待某个异步操作完成。
比如连接数据库:底层是回调风格,对外却想让人用 await:
python
import asyncio
# 模拟底层数据库连接库
# 它不是 async 函数,而是传统的回调风格
def some_low_level_connect(host: str, callback):
print(f"[底层库] 开始连接 {host} ...")
def on_connected():
# 模拟连接成功后,返回一个 connection 对象
connection = {"host": host, "status": "connected"}
callback(connection)
# 模拟网络延迟:1 秒后调用 callback
asyncio.get_running_loop().call_later(1, on_connected)
async def connect_db(host: str = "127.0.0.1:5432"):
# 1. 创建一张"欠条"
future = asyncio.get_running_loop().create_future()
# 2. 调用底层回调式接口,把 future.set_result 当作回调传进去
# 等底层连接成功后,会自动执行:future.set_result(connection)
some_low_level_connect(host, callback=future.set_result)
# 3. 调用者只需要 await,就能拿到最终结果
connection = await future
return connection
async def main():
print("准备连接数据库...")
connection = await connect_db("127.0.0.1:5432")
print("连接成功,拿到结果:")
print(connection)
asyncio.run(main())
Future 把「回调拿到结果」和「await 拿到结果」接在一起。
三种状态
Future 有且仅有三种状态:
| 状态 | 含义 |
|---|---|
| Pending(未完成) | 初始状态,操作还在进行中 |
| Done(已完成) | 操作已结束(成功设了结果,或设了异常) |
| Cancelled(已取消) | 被显式取消 |
核心 API
| 方法 | 作用 |
|---|---|
set_result(value) |
设置结果,状态变为 Done |
set_exception(exc) |
设置异常,状态变为 Done |
result() |
获取结果(未完成时抛 InvalidStateError) |
done() |
是否已完成 |
cancelled() |
是否已取消 |
cancel() |
取消 Future |
add_done_callback(cb) |
注册完成回调 |
get_loop() |
获取绑定的事件循环 |