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.
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())
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.
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.
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())
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.