Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine awaitables like Promise.all

In asynchronous JavaScript, it is easy to run tasks in parallel and wait for all of them to complete using 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)]); } 

I tried to rewrite the latter in 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() 

But it executes my tasks sequentially.

What is the simplest way to await multiple awaitables? Why doesn't my approach work?

like image 554
Tamas Hegedus Avatar asked Dec 20 '15 02:12

Tamas Hegedus


People also ask

Can we use Promise and async await together?

Async/Await is used to work with promises in asynchronous functions. It is basically syntactic sugar for promises. It is just a wrapper to restyle code and make promises easier to read and use. It makes asynchronous code look more like synchronous/procedural code, which is easier to understand.

Can we use await with Promise all?

all() along with making that function as async and promise resulting fetching will be done along with the await keyword.

What is difference between async and Promise?

Promise creation starts the execution of asynchronous functionality. await only blocks the code execution within the async function. It only makes sure that the next line is executed when the promise resolves. So, if an asynchronous activity has already started, await will not have any effect on it.

Can async be Promise?

Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.


2 Answers

The equivalent would be using asyncio.gather:

import asyncio  async def bar(i):   print('started', i)   await asyncio.sleep(1)   print('finished', i)  async def main():   await asyncio.gather(*[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.gather using loop.create_task or asyncio.ensure_future.

EDIT

The original answer used the lower-level asyncio.wait.

like image 63
Jashandeep Sohi Avatar answered Oct 13 '22 06:10

Jashandeep Sohi


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.

like image 43
请叫我小马哥 Avatar answered Oct 13 '22 06:10

请叫我小马哥