I have 2 functions: The first one, def_a
, is an asynchronous function and the second one is def_b
which is a regular function and called with the result of def_a
as a callback with the add_done_callback
function.
My code looks like this:
import asyncio def def_b(result): next_number = result.result() # some work on the next_number print(next_number + 1) async def def_a(number): await some_async_work(number) return number + 1 loop = asyncio.get_event_loop() task = asyncio.ensure_future(def_a(1)) task.add_done_callback(def_b) response = loop.run_until_complete(task) loop.close()
And it's work perfectly.
The problem began when also the second function, def_b
, became asynchronous. Now it looks like this:
async def def_b(result): next_number = result.result() # some asynchronous work on the next_number print(next_number + 1)
But now I can not provide it to the add_done_callback
function, because it's not a regular function.
My question is- Is it possible and how can I provide def_b
to the add_done_callback
function if def_b
is asynchronous?
asyncio is a library to write concurrent code using the async/await syntax. asyncio is used as a foundation for multiple Python asynchronous frameworks that provide high-performance network and web-servers, database connection libraries, distributed task queues, etc.
The syntax async def introduces either a native coroutine or an asynchronous generator. The expressions async with and async for are also valid, and you'll see them later on. The keyword await passes function control back to the event loop. (It suspends the execution of the surrounding coroutine.)
To run an async function (coroutine) you have to call it using an Event Loop. Event Loops: You can think of Event Loop as functions to run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses. Example 1: Event Loop example to run async Function to run a single async function: Python3.
An async function uses the await keyword to denote a coroutine. When using the await keyword, coroutines release the flow of control back to the event loop. To run a coroutine, we need to schedule it on the event loop. After scheduling, coroutines are wrapped in Tasks as a Future object.
add_done_callback
is considered a "low level" interface. When working with coroutines, you can chain them in many ways, for example:
import asyncio async 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 + 1 async def add_success_callback(fut, callback): result = await fut await callback(result) return result loop = 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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With