Asyncio собирать, принося результаты, как они приходят - PullRequest
1 голос
/ 03 октября 2019

Я хочу получать результаты от набора задач, выполняемых gather по мере их поступления для дальнейшей обработки.

# Not real code, but an example

async for response in asyncio.gather(*[aiohttp.get(url) for url in ['https://www.google.com', 'https://www.amazon.com']]):
    await process_response(response)

В настоящее время я могу использовать метод gather длязапустить все get одновременно, но нужно подождать, пока они все не завершат их обработку. Я все еще плохо знаком с Python async / await, поэтому, возможно, есть какой-то очевидный способ сделать это, которого мне не хватает.

# What I can do now
responses = await asyncio.gather(*[aiohttp.get(url) for url in ['https://www.google.com', 'https://www.amazon.com']])
await asyncio.gather(*[process_response(response) for response in responses])

Спасибо!

1 Ответ

1 голос
/ 03 октября 2019

gather, как вы уже отметили, будет ждать, пока все сопрограммы не будут выполнены, поэтому вам нужно найти другой путь.

Например, вы можете использовать функцию asyncio.as_completed , которая кажетсяделай то, что хочешь.

import asyncio


async def echo(t):
    await asyncio.sleep(t)
    return t



async def main():
    coros = [
        echo(3),
        echo(2),
        echo(1),
    ]

    for first_completed in asyncio.as_completed(coros):
        res = await first_completed
        print(f'Done {res}')


asyncio.run(main())

Результат:

Done 1
Done 2
Done 3
[Finished in 3 sec]
...