Combina objetos como Promise.all

En JavaScript asíncrono, es fácil ejecutar tareas en paralelo y esperar a que todas se completen utilizando Promise.all :

 async function bar(i) { console.log('started', i); await delay(1000); console.log('finished', i); } async function foo() { await Promise.all([bar(1), bar(2)]); } // This works too: async function my_all(promises) { for (let p of promises) await p; } async function foo() { await my_all([bar(1), bar(2), bar(3)]); } 

Intenté reescribir este último en python:

 import asyncio async def bar(i): print('started', i) await asyncio.sleep(1) print('finished', i) async def aio_all(seq): for f in seq: await f async def main(): await aio_all([bar(i) for i in range(10)]) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close() 

Pero ejecuta mis tareas secuencialmente.

¿Cuál es la forma más sencilla de esperar múltiples pendientes? ¿Por qué no funciona mi enfoque?

El equivalente sería usar asyncio.wait :

 import asyncio async def bar(i): print('started', i) await asyncio.sleep(1) print('finished', i) async def main(): await asyncio.wait([bar(i) for i in range(10)]) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close() 

¿Por qué no funciona mi enfoque?

Porque cuando await cada artículo en la secuencia, bloqueas esa rutina. Entonces, en esencia, tienes un código síncrono que se hace pasar por async. Si realmente lo deseara , podría implementar su propia versión de asyncio.wait utilizando loop.create_task o asyncio.ensure_future .

EDITAR

Como mencionó Andrew, también puedes usar asyncio.gather .

Noté que asyncio.gather () puede ser una mejor manera de esperar que no sea asyncio.wait () si queremos resultados ordenados.

Como indica la documentación, el orden de los valores de los resultados del método asyncio.gather () corresponde al orden de los pendientes en aws. Sin embargo, el orden de los valores de los resultados de asyncio.wait () no hará lo mismo. Puede probarlo.