Does it make sense to use async with code that has no sleep()?

Viewed 266

I've read a lot of different articles that explain the async in Python. But they all give an example with asyncio.sleep(x), like this one:

import asyncio

async def test1 ():
    await asyncio.sleep(1)
    print(1)

async def test2 ():
    print(2)

async def main ():
    await asyncio.gather(test1(), test2())

asyncio.run(main()) #prints 2, then 1

And in this case everything's clear for me: await in function test1 says that during the execution of asyncio.sleep we can do something other, for example execute function test2.

What I don't understand, is that how can the async be useful, if I don't use sleeps in my code? How can I run functions concurrently in that case? For example, how do I run concurrently functions test1 and test2 in the example below?

import asyncio
import time

async def calculate (a):
    return a**a

async def test1 ():
    x = await calculate(1111111)
    print('done!')

async def test2 ():
    for i in range(100):
        print('.', end='')

async def main ():
    await asyncio.gather(test1(), test2())

asyncio.run(main()) #prints 'done!' before the dots
1 Answers

You can achieve this with tasks.

Tasks are used to schedule coroutines concurrently.

When a coroutine is wrapped into a Task with functions like asyncio.create_task() (see official documentation ) the coroutine is automatically scheduled to run soon:

import asyncio
import time


async def calculate(a):
    return a**a


async def test1():
    # Schedule calculate(a) to run soon concurrently
    # with "main()".
    task = asyncio.create_task(calculate(11111))

    # "task" can now be used to cancel "calculate(a)", or
    # can simply be awaited to wait until it is complete:
    await task
    print('done!')


async def dots_printer():
    for i in range(100):
        print('.', end='')
        

async def test2():
    # Schedule dots_printer() to run soon concurrently
    # with "main()".
    task = asyncio.create_task(dots_printer())

    # "task" can now be used to cancel "dots_printer()", or
    # can simply be awaited to wait until it is complete:
    await task


async def main():
    await asyncio.gather(test1(), test2())


asyncio.run(main()) #prints the dots before 'done!'
Related