Python Asyncio:在协程中等待另一协程的中间结果
跨类协程间获取中间结果的实现方案
你这个场景其实就是要在两个分属不同类的协程之间做中间结果的同步等待嘛,这在异步编程里挺常见的,用asyncio.Future就能完美解决——它就像个专门装结果的“快递盒”,co_A把计算好的中间结果放进去,co_B在需要的地方等着签收,完全贴合你的需求。
下面是具体的实现代码,我会给你讲清楚每一步的逻辑:
核心逻辑
- 先创建一个共享的
asyncio.Future对象,让class_A和class_B的实例都能拿到它 co_A在算出需要的中间结果时,调用future.set_result()把结果塞进去co_B在需要结果的位置,用await future来等着,直到结果就绪再继续往下执行
完整代码示例
import asyncio class class_A: def __init__(self, shared_future): self.shared_future = shared_future # 把共享的Future传进来 async def co_A(self): print("co_A: 开始跑第一个耗时任务...") await asyncio.sleep(2) # 模拟耗时操作 # 算出co_B要的中间结果 intermediate_result = {"status": "done", "data": "我是co_A的中间结果"} print("co_A: 中间结果搞定,放进共享Future里") self.shared_future.set_result(intermediate_result) # 放结果,触发co_B的等待 print("co_A: 继续跑剩下的耗时任务...") await asyncio.sleep(3) # 模拟后续操作 print("co_A: 所有任务都做完啦") class class_B: def __init__(self, shared_future): self.shared_future = shared_future # 同样传入共享Future async def co_B(self): print("co_B: 先跑一段自己的耗时任务...") await asyncio.sleep(1) # 模拟耗时操作 # 等着拿co_A的中间结果 print("co_B: 等co_A的中间结果ing...") result = await self.shared_future # 这里会暂停,直到Future里有结果 print(f"co_B: 拿到结果啦!内容是: {result}") print("co_B: 继续跑剩下的任务...") await asyncio.sleep(2) # 模拟后续操作 print("co_B: 我的任务也做完啦") async def main(): # 创建共享的Future对象,这是两个协程的"桥梁" shared_future = asyncio.Future() # 实例化两个类,把共享Future传进去 a_instance = class_A(shared_future) b_instance = class_B(shared_future) # 这里用asyncio.gather模拟调度器同时启动两个协程 await asyncio.gather(a_instance.co_A(), b_instance.co_B()) if __name__ == "__main__": asyncio.run(main())
关键细节说明
- 共享Future的传递:通过构造函数把Future传给两个类的实例,确保它们操作的是同一个对象,这是实现同步的关键
await future的行为:如果co_B先跑到等待的地方,它会自动挂起,不会占用资源;等co_A把结果放进去后,co_B会立刻被唤醒继续执行。如果co_A已经把结果放进去了,await会直接返回结果,不会等- 多次调度的情况:如果你的调度器是定期重复调用这两个协程(比如每隔一段时间跑一次),那每次调度都要重新创建一个新的Future,避免和上一次的结果搞混。比如这样写调度逻辑:
async def periodic_scheduler(): while True: # 每次调度都新建一个共享Future shared_future = asyncio.Future() a_instance = class_A(shared_future) b_instance = class_B(shared_future) await asyncio.gather(a_instance.co_A(), b_instance.co_B()) await asyncio.sleep(10) # 每隔10秒调度一次 asyncio.run(periodic_scheduler())
这样每次周期的协程都用独立的Future,不会互相干扰。
内容的提问来源于stack exchange,提问作者Beckicious
相关产品推荐
相关产品推荐

