协程是生成器函数,它既可以产生值也可以从外部接受值。使用协程的好处是我们可以暂停函数的执行并在以后恢复它。在网络操作的情况下,在我们等待响应的同时暂停函数的执行是有意义的。我们可以花时间运行其他功能。
未来就像Promise
Javascript中的对象一样。它就像一个占位符,代表着将在未来实现的价值。在上述情况下,在等待网络I / O时,一个函数可以给我们一个容器,保证在操作完成时它将用值填充该容器。我们保留了将来的对象,当它满足时,我们可以在其上调用方法以检索实际结果。
直接回答:你并不需要ensure_future
,如果你不想要的结果。如果您需要结果或检索发生的异常,它们会很好。
额外积分:我将选择run_in_executor
并传递一个Executor
实例来控制最大工人数。
说明和示例代码
在第一个示例中,您正在使用协程。该wait
函数接收一堆协程并将它们组合在一起。这样就wait()
完成了所有协程的耗尽(返回所有值的完成/完成)。
loop = get_event_loop() #
loop.run_until_complete(wait(coros))
该run_until_complete
方法将确保循环有效直到执行完成。请注意在这种情况下您如何无法获得异步执行的结果。
在第二个示例中,您将使用ensure_future
函数包装协程并返回的Task
对象Future
。协程计划在您调用时在主事件循环中执行ensure_future
。返回的future / task对象还没有值,但是随着时间的推移,当网络操作完成时,future对象将保存操作的结果。
from asyncio import ensure_future
futures = []
for i in range(5):
futures.append(ensure_future(foo(i)))
loop = get_event_loop()
loop.run_until_complete(wait(futures))
因此,在此示例中,我们正在做相同的事情,除了使用期货而不是仅使用协程。
让我们看一下如何使用asyncio /协程/期货的示例:
import asyncio
async def slow_operation():
await asyncio.sleep(1)
return 'Future is done!'
def got_result(future):
print(future.result())
# We have result, so let's stop
loop.stop()
loop = asyncio.get_event_loop()
task = loop.create_task(slow_operation())
task.add_done_callback(got_result)
# We run forever
loop.run_forever()
在这里,我们create_task
在loop
对象上使用了方法。ensure_future
将在主事件循环中安排任务。这种方法使我们能够在选择的循环中安排协程。
我们还看到了add_done_callback
在任务对象上使用方法添加回调的概念。
A Task
是done
当协程返回值,引发异常或被取消时。有检查这些事件的方法。
我写了一些有关这些主题的博客文章,可能会有所帮助:
当然,您可以在官方手册上找到更多详细信息:https : //docs.python.org/3/library/asyncio.html
ensure_future()
?而且,如果我确实需要结果,就不能使用run_until_complete(gather(coros))
吗?