What would be equivalent to JavaScript promise.all() in Python?

Question:

In JavaScript we can run functions in parallel using promise.all() but it doesn’t exist in python, how can I run two functions in parallel in Python?

import discord
import asyncio                          
from discord.ext import tasks, commands

client = discord.Client()
client = commands.Bot(command_prefix='!')

@client.event
async def on_ready():
 print("Monitor Ativo!")
 promise.start()
async def bar():                                                                       
 print("sjj")                                                                                                                                   

async def ba():                                                                      
 print("dhhdh")                                                                                                           

@tasks.loop(seconds=5)
async def promise():                             
 await asyncio.wait([bar(), ba()])

But I noticed that when I run the function it always runs the last function first, so it can’t be running in parallel right?

Since it’s always running the last function before the first one, so it has a pattern, and so it can’t be running in parallel, how can I run two functions in parallel in python, equivalent to promise.all in javascript.

Asked By: user15594988

||

Answers:

You can use asyncio.create_task.

Code:

import asyncio
import time


async def bar():
    await asyncio.sleep(5)
    print("sjj")


async def ba():
    await asyncio.sleep(3)
    print("dhhdh")


async def promise():
    tasks = [asyncio.create_task(bar()), asyncio.create_task(ba())]
    for task in tasks:
        await task

asyncio.run(promise())
Answered By: KetZoomer

The answer by @KetZoomer works good, but here’s how to scale easier with a syntax closer to what you wanted and properly return the return values:

import asyncio
import time

start_time = time.time()


async def bar():
    await asyncio.sleep(10)
    print(f"barttotal time elapsed: {time.time() - start_time}s")
    return 5


async def ba():
    await asyncio.sleep(3)
    print(f"battotal time elapsed: {time.time() - start_time}s")
    return 19

async def b(num):
    await asyncio.sleep(10)
    print(f"bttotal time elapsed: {time.time() - start_time}styour number was {num}")
    return 2000


async def promise_all(funcs):
    tasks = [asyncio.create_task(func()) for func in funcs]
    return [await task for task in tasks]

print(asyncio.run(promise_all([bar, ba, lambda: b(5)])))

If you run this script, you’ll see the output is (specific decimals might change, bar vs b might change):

$ py -3 banana.py
ba  total time elapsed: 3.002803325653076s
bar total time elapsed: 10.00796914100647s
b   total time elapsed: 10.00804877281189s  your number was 5
Output: [5, 19, 2000]

Note: as you can see by the last function (the b function), if you want to pass in a variable, use a lambda.

Answered By: Samathingamajig
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.