Цепочка asyncio сопрограмм встроена в asyncio.gather - PullRequest
4 голосов
/ 22 февраля 2020

У меня есть гипотетический сценарий asyncio.gather:

await asyncio.gather(
    cor1,
    [cor2, cor3],
    cor4,
)

Я бы хотел, чтобы cor2 и cor3 были выполнены по порядку. Есть ли какой-нибудь краткий способ сделать что-то кроме определения внешней сопрограммы, например:

async def cor2_cor3():
    await cor2
    await cor3

await asyncio.gather(
    cor1,
    cor2_cor3,
    cor4,
)

Есть ли более чистый ярлык для этого?

1 Ответ

3 голосов
/ 22 февраля 2020

Есть ли более чистый ярлык для этого?

asyncio не предоставляет один из коробки. Если бы у асинхронных задач был метод, эквивалентный JavaScript Promise.then, вы могли бы использовать asyncio.create_task(cor2()).then(cor3()). Но эквивалент asyncio, add_done_callback, является более низкоуровневой конструкцией, которая просто устанавливает обратный вызов без создания нового будущего, что делает его неудобным для создания цепочек.

Выполнение сопрограмм для того, чтобы вам нужно было написать простую служебную функцию, например (непроверенную):

async def chain(*aws):
    ret = None
    for aw in aws:
        ret = await aw
    return ret

Затем вы можете вызвать gather как:

await asyncio.gather(cor1(), chain(cor2(), cor3()), cor4())
...