Python is a fascinating language. I have learnt many a new things while working on it, and a few surprises have come along the way as well.
Well anyway, I’ll show ya what I have learnt so far.
Let’s say we have an ordinary python
async def function that does nothing much but returns a string.
async def return_hello(): print('executes once') await asyncio.sleep(2) return 'hello_world'
Another thing I have found is, I need to always create an event loop to get things to work. So let’s get to work!
event_loop = asyncio.new_event_loop()
Now we need to set this event loop for the current context.
Now comes the fun part. We create a task that executes the coroutine
Important: This task starts executing the coroutine the instant we create it. This means that anything we execute after creating it will run in a parallel fashion.
task = asyncio.ensure_future(return_hello()) print('runs before anything else')
If we print something after the
ensure_future call, it might get executed before the first line in the coroutine.
If we would like to obtain the result of our “promise”, then all we got to say is:
hello = asyncio.get_event_loop().run_until_complete(task) print(hello) assert hello == 'hello_world'
The above line blocks the thread till the response arrives. It can be in the same thread or any other thread as well.
Now let me explain how this is closely related to how promises behave. Promises essentially store their resolved or rejected result after resolution or rejection. That means that at any point in time, one may
.then them and get that result. Similarly, using tasks we are able to achieve this same caching behavior.
It is helpful when there is certain data that is needed by different threads of execution and you do not want to fetch the data multiple times in those threads. You only want to fetch it once and make those threads hungrily wait for that data to finally resolve before they can consume it.
The full program is as follows:
import asyncio async def return_hello(): print('executes once') await asyncio.sleep(2) return 'hello_world' event_loop = asyncio.new_event_loop() asyncio.set_event_loop(event_loop) task = asyncio.ensure_future(return_hello()) print('runs before anything else') hello = asyncio.get_event_loop().run_until_complete(task) print(hello) assert hello == 'hello_world'
The output might be:
runs before anything else executes once hello_world