Combine awaitables like Promise.all Combine awaitables like Promise.all python-3.x python-3.x

Combine awaitables like Promise.all


The equivalent would be using asyncio.wait:

import asyncioasync 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()

Why doesn't my approach work?

Because when you await each item in seq, you block that coroutine. So in essence, you have synchronous code masquerading as async. If you really wanted to, you could implement your own version of asyncio.wait using loop.create_task or asyncio.ensure_future.

EDIT

As Andrew mentioned, you can also use asyncio.gather.


I noticed that asyncio.gather() may be a better way to await other than asyncio.wait() if we want ordered results.

As the docs indicates, the order of result values from asyncio.gather() method corresponds to the order of awaitables in aws. However, the order of result values from asyncio.wait() won't do the same thing.You can test it.


https://docs.python.org/3/library/asyncio-task.html#asyncio.gather

asyncio.gather() will return the list of output from each async function calls.

import asyncioasync def bar(i):    print('started', i)    await asyncio.sleep(1)    print('finished', i)    return iasync def main():    values = await asyncio.gather(*[bar(i) for i in range(10)])    print(values)asyncio.run(main())

This method, gather, takes arbitrary number of args for the concurrent jobs instead of a list, so we unpack.

It's very common to need this intermediate value, values in my eg, instead of designing your method to have side affects.