Future 对象¶
源代码: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py
Future 对象用于连接低级基于回调的代码和高级 async/await 代码。
Future 函数¶
- asyncio.isfuture(obj)¶
如果 obj 是以下之一,则返回
True
一个
asyncio.Future
实例,一个
asyncio.Task
实例,一个带有
_asyncio_future_blocking
属性的类似 Future 的对象。
在 3.5 版本加入。
- asyncio.ensure_future(obj, *, loop=None)¶
返回
如果 obj 是
Future
、Task
或类似 Future 的对象(使用isfuture()
进行测试),则返回 obj 本身。如果 obj 是一个协程(使用
iscoroutine()
进行测试),则返回一个包装 obj 的Task
对象;在这种情况下,协程将由ensure_future()
调度。如果 obj 是一个可等待对象(使用
inspect.isawaitable()
进行测试),则返回一个将等待 obj 的Task
对象。
如果 obj 不属于上述任何一种情况,则会引发
TypeError
。版本 3.5.1 中有改变: 该函数接受任何 可等待对象。
从 3.10 版本开始废弃: 如果 obj 不是类似 Future 的对象且未指定 loop 且没有正在运行的事件循环,则会发出弃用警告。
- asyncio.wrap_future(future, *, loop=None)¶
将
concurrent.futures.Future
对象包装为asyncio.Future
对象。从 3.10 版本开始废弃: 如果 future 不是类似 Future 的对象且未指定 loop 且没有正在运行的事件循环,则会发出弃用警告。
Future 对象¶
- class asyncio.Future(*, loop=None)¶
Future 表示异步操作的最终结果。非线程安全。
Future 是一个 可等待对象。协程可以等待 Future 对象,直到它们有结果或设置了异常,或者直到它们被取消。Future 可以被多次等待,结果是相同的。
通常,Future 用于使低级基于回调的代码(例如在通过 asyncio 传输 实现的协议中)与高级 async/await 代码互操作。
经验法则是,永远不要在面向用户的 API 中公开 Future 对象,并且创建 Future 对象的推荐方法是调用
loop.create_future()
。这样,替代的事件循环实现可以注入它们自己优化的 Future 对象实现。版本 3.7 中有改变: 添加了对
contextvars
模块的支持。从 3.10 版本开始废弃: 如果未指定 loop 且没有正在运行的事件循环,则会发出弃用警告。
- result()¶
返回 Future 的结果。
如果 Future 已经 完成 并且已通过
set_result()
方法设置了结果,则返回结果值。如果 Future 已经 完成 并且已通过
set_exception()
方法设置了异常,则此方法会引发该异常。如果 Future 已被 取消,则此方法会引发
CancelledError
异常。如果 Future 的结果尚不可用,则此方法会引发
InvalidStateError
异常。
- set_result(result)¶
将 Future 标记为 完成 并设置其结果。
如果 Future 已 完成,则会引发
InvalidStateError
错误。
- set_exception(exception)¶
将 Future 标记为 完成 并设置异常。
如果 Future 已 完成,则会引发
InvalidStateError
错误。
- done()¶
如果 Future 已 完成,则返回
True
。如果 Future 已被 取消,或者已通过
set_result()
或set_exception()
调用设置了结果或异常,则 Future 为 完成 状态。
- cancelled()¶
如果 Future 已被 取消,则返回
True
。此方法通常用于在为 Future 设置结果或异常之前检查 Future 是否未被 取消。
if not fut.cancelled(): fut.set_result(42)
- add_done_callback(callback, *, context=None)¶
添加一个回调函数,当 Future 完成 时运行。
callback 会以 Future 对象作为其唯一参数被调用。
如果 Future 在调用此方法时已 完成,则回调函数会通过
loop.call_soon()
调度。可选的仅限关键字参数 context 允许为 callback 指定一个自定义的
contextvars.Context
来运行。如果未提供 context,则使用当前上下文。functools.partial()
可用于向回调函数传递参数,例如:# Call 'print("Future:", fut)' when "fut" is done. fut.add_done_callback( functools.partial(print, "Future:"))
版本 3.7 中有改变: 添加了 context 仅限关键字参数。更多详情请参阅 PEP 567。
- remove_done_callback(callback)¶
从回调列表中删除 callback。
返回移除的回调数量,通常为 1,除非回调被添加多次。
- cancel(msg=None)¶
取消 Future 并调度回调。
如果 Future 已 完成 或已 取消,则返回
False
。否则,将 Future 的状态更改为 取消,调度回调,并返回True
。版本 3.9 中有改变: 添加了 msg 参数。
- exception()¶
返回在此 Future 上设置的异常。
只有当 Future 处于 完成 状态时,才返回异常(如果没有设置异常,则返回
None
)。如果 Future 已被 取消,则此方法会引发
CancelledError
异常。如果 Future 尚未 完成,此方法会引发
InvalidStateError
异常。
- get_loop()¶
返回 Future 对象绑定的事件循环。
在 3.7 版本加入。
此示例创建了一个 Future 对象,创建并调度了一个异步任务来为 Future 设置结果,并等待直到 Future 有结果。
async def set_after(fut, delay, value):
# Sleep for *delay* seconds.
await asyncio.sleep(delay)
# Set *value* as a result of *fut* Future.
fut.set_result(value)
async def main():
# Get the current event loop.
loop = asyncio.get_running_loop()
# Create a new Future object.
fut = loop.create_future()
# Run "set_after()" coroutine in a parallel Task.
# We are using the low-level "loop.create_task()" API here because
# we already have a reference to the event loop at hand.
# Otherwise we could have just used "asyncio.create_task()".
loop.create_task(
set_after(fut, 1, '... world'))
print('hello ...')
# Wait until *fut* has a result (1 second) and print it.
print(await fut)
asyncio.run(main())
重要
Future 对象旨在模拟 concurrent.futures.Future
。主要区别包括:
与 asyncio Future 不同,
concurrent.futures.Future
实例不能被等待。asyncio.Future.result()
和asyncio.Future.exception()
不接受 timeout 参数。当 Future 未 完成 时,
asyncio.Future.result()
和asyncio.Future.exception()
会引发InvalidStateError
异常。通过
asyncio.Future.add_done_callback()
注册的回调不会立即被调用。它们而是通过loop.call_soon()
调度。asyncio Future 不兼容
concurrent.futures.wait()
和concurrent.futures.as_completed()
函数。asyncio.Future.cancel()
接受可选的msg
参数,而concurrent.futures.Future.cancel()
不接受。