我还不确定何时使用ensure_future,我想知道这是否是我想要/需要它的情况.
请考虑以下代码
import asyncio
loop = asyncio.get_event_loop()
async def do_work(count):
for i in range(count):
if i % 10000 == 0:
await asyncio.sleep(0.1)
print(count)
return i
async def do_batch_work():
res1 = do_work(100000)
res2 = do_work(100)
await asyncio.wait([res1, res2])
return res1, res2
def main():
loop = asyncio.get_event_loop()
res1, res2 = loop.run_until_complete(do_batch_work())
print(res1.result())
print(res2.result())
loop.close()
main()
这打印:
100
100000
Traceback (most recent call last):
File "more_async.py", line 30, in <module>
main()
File "more_async.py", line 26, in main
print(res1.result())
AttributeError: 'coroutine' object has no attribute 'result'
异步代码按预期运行并按预期顺序打印出来,但loop.run_until_complete(…)不允许我访问底层结果,因为协程对象似乎无法获得结果.
我可以通过如下更改方法来解决这个问题
async def do_batch_work():
res1 = asyncio.ensure_future(do_work(100000))
res2 = asyncio.ensure_future(do_work(100))
await asyncio.wait([res1, res2])
return res1, res2
通过调用asyncio.ensure_future(…),我确保将任务返回到我可以调用result()的位置.
我想知道,这是处理它的正确方法吗?如果我关心那个协程的结果,还是我还有另一种我不知道的方法,我是否需要使用ensure_future?
最佳答案
async def do_batch_work():
res1 = do_work(100000)
res2 = do_work(100)
await asyncio.wait([res1, res2])
return res1, res2
res1和res2只是该示例中的协同程序,而不是Future对象,因此没有结果属性.当您使用ensure_future()时,res1和res2现在是Future对象,这就是您可以访问result属性的原因. wait()在两种情况下的工作方式相同,并且两个代码中的结果都是同等生成的,只是你的函数没有返回正确的对象.
如果要修改第一个示例,则wait()将返回所需的Future对象作为第一个项目.
async def do_batch_work():
res1 = do_work(100000)
res2 = do_work(100)
(res1, res2), _ = await asyncio.wait([res1, res2])
return res1, res2