python asyncio add_done_callback with async def python asyncio add_done_callback with async def python-3.x python-3.x

python asyncio add_done_callback with async def


add_done_callback is considered a "low level" interface. When working with coroutines, you can chain them in many ways, for example:

import asyncioasync def my_callback(result):    print("my_callback got:", result)    return "My return value is ignored"async def coro(number):    await asyncio.sleep(number)    return number + 1async def add_success_callback(fut, callback):    result = await fut    await callback(result)    return resultloop = asyncio.get_event_loop()task = asyncio.ensure_future(coro(1))task = add_success_callback(task, my_callback)response = loop.run_until_complete(task)print("response:", response)loop.close()

Keep in mind add_done_callback will still call the callback if your future raises an exception (but calling result.result() will raise it).


This only works for one future job, if you have multiple async jobs, they will blocks each other, a better way is using asyncio.as_completed() to iterate future list:

import asyncioasync def __after_done_callback(future_result):    # await for something...    passasync def __future_job(number):    await some_async_work(number)    return number + 1loop = asyncio.get_event_loop()tasks = [asyncio.ensure_future(__future_job(x)) for x in range(100)]  # create 100 future jobsfor f in asyncio.as_completed(tasks):    result = await f    await __after_done_callback(result)loop.close()


You can try the aiodag library. It's a very lightweight wrapper around asyncio that abstracts away some of the async plumbing that you usually have to think about. From this example you won't be able to tell that things are running asynchronously since it's just 1 task that depends on another, but it is all running async.

import asynciofrom aiodag import task@taskasync def def_b(result):    # some asynchronous work on the next_number    print(result + 1)@taskasync def def_a(number):    await asyncio.sleep(number)    return number + 1async def main():    a = def_a(1)    b = def_b(a)  # this makes task b depend on task a    return await bloop = asyncio.get_event_loop()asyncio.set_event_loop(loop)response = loop.run_until_complete(main())