在Python中进行异步循环

时间:2018-11-26 18:07:19

标签: python asynchronous python-asyncio

以下代码输出如下:

1 sec delay, print "1", 
1 sec delay, print "2", 
1 sec delay, print "1", 
1 sec delay, print "2"

如何修改使其像这样运行:

1 sec delay, print "1", print "1",
1 sec delay, print "2", print "2"

我希望它运行,以便for循环的两个实例开始同时执行。在执行每个实例时,它们将同时遇到first()函数,然后同时遇到second()函数,因此按上述顺序打印。

代码:

import asyncio

async def first():
    await asyncio.sleep(1)
    return "1"

async def second():
    await asyncio.sleep(1)
    return "2"

async def main():     
    for i in range(2):
      result = await first()
      print(result)
      result2 = await second()
      print(result2)


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

3 个答案:

答案 0 :(得分:2)

使用aysncio库,您可以使用aysncio.gather()

loop.run_until_complete(asyncio.gather(
  first(),
  second()
))

如果您还并行发送HTTP请求,这可能会派上用场:

loop.run_until_complete(asyncio.gather(
  request1(),
  request2()
))

答案 1 :(得分:2)

查看所需的输出,似乎目标是保持单个迭代不变-即依次运行firstsecond-但并行执行两个循环迭代。

假设您只想修改main(),可以这样实现:

async def main():
    async def one_iteration():
        result = await first()
        print(result)
        result2 = await second()
        print(result2)
    coros = [one_iteration() for _ in range(2)]
    await asyncio.gather(*coros)

上面的代码不是按顺序进行迭代,而是为每个迭代任务创建一个协程,并使用asyncio.gather并行执行所有迭代。

请注意,仅创建协程不会开始执行它,因此大量的coros不会阻塞事件循环。

答案 2 :(得分:1)

要同时运行这两个功能,可以使用gather。但是,结果将按照您提供的顺序提供给您。例如,如果您这样做

results = await asyncio.gather(first(), second())

然后您将退回[the result of first(), the result of second()]。如果您想在每个人返回时都做某事,则应该显式使用Tasksadd callbacks