Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python call callback after async function is done

I'm trying to call a callback once a async function is done running

Here's an example of what im trying to do:

import asyncio

async def asyncfunction():
    print('Hello')
    await asyncio.sleep(10)
    print('World')
    return 10

def callback(n):
    print(f'The async function returned: {n}')

loop = asyncio.get_event_loop()

# Will block the print until everything is done
callback(loop.run_until_complete(asyncfunction()))
print('Hey')

Here's what that does:

Hello
World
The async function returned: 10
Hey

And here's what I want it to do
Edit: The position of the 'Hey' doesn't really matter, as long as it doesn't have to wait for the async function to be done

Hello
Hey
World
The async function returned: 10

Edit: after some testing I have found a way that does what I want, although I don't know if its the best way to do it

import asyncio
import threading

async def asyncfunction():
    print('Hello')
    await asyncio.sleep(10)
    print('World')
    return 10

def callback(n):
    print(f'The async function returned: {n}')

def wrapper(loop):
    callback(loop.run_until_complete(asyncfunction()))

loop = asyncio.get_event_loop()
thr = threading.Thread(target=wrapper,args=(loop,))
thr.start()
print('Hey')
like image 399
mat Avatar asked Jan 01 '23 05:01

mat


1 Answers

Using Threading with asyncio is just confusing and most likely not what you want. run_until_complete is one of the blocking call and should likely be the last statement in an asyncio program.

To add code after calling an async function, just create create a wrapper

async def myfunc():
  n = await asyncfunction()
  callback(n)

loop.run_until_complete(myfunc()) # from python 3.7, asyncio.run(myfunc())

If you just want to schedule some code to run asynchronously and continue with something else, create a task and await at the end

async def a_main():
  task = asyncio.ensure_future(myfunc()) # from python 3.7, asyncio.create_task(...)
  print("Hey")
  # Anything else to run
  await task # wait for the task to complete

loop.run_until_complete(a_main())
like image 101
balki Avatar answered Jan 13 '23 20:01

balki