Python异步编程asyncio(四):Future
1 引言
在之前的文章中,我们探讨了 Coroutine (协程)——一种异步执行单元,Task (任务)——协程的调度封装。在实际的异步系统中,“产生结果的时刻” 与 “消费结果的时刻” 往往是解耦的。当一个异步操作正在后台运行,而我们需要一个“凭证”来代表那个尚未抵达的结果时,该由谁来充当这个角色?
答案就是 Future。
2 什么是Future?
Future 是一个Awaitable对象,作为我们尚未拥有但希望将来会有的结果的容器。
3 Future的行为模式
3.1 状态
它是生产者设置返回值结果的标准化方式。
import asyncio
# 创建一个 Future 对象
f = asyncio.Future()
print(f"Is done? {f.done()}") # False
print(f"Is cancelled? {f.cancelled()}") # False
# 尝试在没有结果时获取结果会抛出 InvalidStateError
try:
f.result()
except asyncio.InvalidStateError:
print("Result is not set yet!")
# 设置结果
f.set_result("Success!")
print(f"Is done now? {f.done()}") # True
print(f"Result: {f.result()}") # Success!
3.2 填充结果
通过 loop.call_later 模拟一个延迟任务,在 3 秒后填充 Future 的值。
import asyncio
import typing
async def consumer(awaitable: typing.Awaitable) -> str:
print("Consumer: Waiting for the result...")
# 暂停在这里,直到 awaitable (Future) 被填充
result = await awaitable
return f"Consumer received: {result}"
async def main():
loop = asyncio.get_running_loop()
f = loop.create_future()
# 模拟 3 秒后由生产者设置结果
loop.call_later(3, f.set_result, 'Hello Future!')
res = await consumer(f)
print(res)
asyncio.run(main())
3.3 填充异常
import asyncio
import typing
async def func(awaitable: typing.Awaitable)-> str:
try:
result = await awaitable
except Exception as e:
print("oops!")
return f"Error: {e}"
else:
return result
f = asyncio.Future()
loop = asyncio.get_event_loop()
loop.call_later(1, f.set_exception, ValueError("test error"))
res = loop.run_until_complete(func(f))
print(res)
由于我们将 set_result 改为 set_exception,输出将是:
oops!
Error: test error
嵌套的 Awaitable 也可以工作:
res = loop.run_until_complete(func(func(f)))
输出将是:
oops!
oops!
Error: test error
它也可以与 asyncio.gather 一起工作:
res = loop.run_until_complete(asyncio.gather(func(f), func(func(f))))
输出将是:
oops!
oops!
oops!
['Error: test error', 'Error: test error']
3.4 回调机制
为 Future 添加完成 Callback:
import asyncio
def callback(fut: asyncio.Future) -> None:
print("Future done with result:", fut.result())
loop = asyncio.new_event_loop()
f = loop.create_future()
f.add_done_callback(callback)
f.add_done_callback(lambda f: loop.stop())
f.set_result("Hello, Future!")
loop.run_forever()
输出:
Future done with result: Hello, Future!
本文版权归作者:ixbwer所有,转载请注明原文链接:https://www.cnblogs.com/ixbwer/p/19580570,否则保留追究法律责任的权利。

浙公网安备 33010602011771号