Replace callback helper function to pass return value from coroutine into another function

Viewed 162
import asyncio

async def f():
    await asyncio.sleep(2.5)
    return "return value from f after 2.5 seconds"

def g(x):
    print(x)

async def main():
    ##############################################
    async def callback_helper(original, callback):
        callback(await original())
    asyncio.create_task(callback_helper(f, g))
    ##############################################
    for i in range(1, 5):
        await asyncio.sleep(1)
        print(i, "seconds in main")

asyncio.run(main())

This does exactly what I want:

1 seconds in main
2 seconds in main
return value from f after 2.5 seconds
3 seconds in main
4 seconds in main

I can only modify the code between the #################### lines. I cannot change f, g or the rest of main. Is there a more elegant way to do this? It seems weird that I have to define a "callback helper function", first. How can I run a coroutine and pass the return value into another function without blocking? All I want to do is to call g with the return value from f once it finished. I think there must be something in asyncio for this.

1 Answers

The alternative to awaiting the coroutine in a wrapper coroutine is to use add_done_callback, which is available on all futures, and therefore on tasks as well:

asyncio.create_task(f()).add_done_callback(lambda fut: g(fut.result()))
Related