Skip to content
BetaDE
Lesson 34 of 35Python

Python · Lesson 34 · 30 minutes

async and await

What you'll learn

  • Understand what “waiting at the same time” means
  • Work with async def, await and asyncio.run
  • Run several tasks in parallel with asyncio.gather

Waiting without standing around

Imagine you’re cooking pasta and baking a pizza at the same time. You don’t stand in front of the pot for 10 minutes and then in front of the oven for 15 – you start both and do something else until one is ready. That’s exactly what asynchronous programming is.

Good to know: Codelix runs a learning version of asyncio with a simulated clock: the order is the same as in real Python, but you don’t actually have to wait. asyncio.zeit() shows you the simulated time – this function only exists here (“zeit” is German for time).

async def and await

A function with async def is a coroutine. With await it waits for something without blocking the whole program. Everything is started with asyncio.run():

import asyncio

async def cook(dish, minutes):
    print(f"{dish} starts")
    await asyncio.sleep(minutes)
    print(f"{dish} ready after {minutes} minutes")

async def main():
    await cook("Pasta", 10)
    await cook("Pizza", 15)
    print("Total time:", asyncio.zeit())

asyncio.run(main())

Here everything is still cooked one after the other: 25 minutes.

At the same time with gather

asyncio.gather() starts several coroutines at once and waits until all of them are finished:

import asyncio

async def cook(dish, minutes):
    print(f"{dish} starts")
    await asyncio.sleep(minutes)
    print(f"{dish} ready")
    return dish

async def main():
    results = await asyncio.gather(cook("Pasta", 10), cook("Pizza", 15))
    print(results)
    print("Total time:", asyncio.zeit())

asyncio.run(main())

Now everything only takes as long as the longest dish: 15 minutes.

Remember: async is worth it when a program does a lot of waiting – for the internet, for files or for a robot sensor. It doesn’t make calculations faster.

Quick check

Before you start the task: what does this program print? Type your guess – then Python works it out.

import asyncio


async def say(text, delay):
    await asyncio.sleep(delay)
    print(text)


async def main():
    await asyncio.gather(say("A", 0.2), say("B", 0.1))


asyncio.run(main())

Your task

Your turn

A robot should do three things at the same time: start the motor (2 seconds), calibrate the sensor (1 second) and run a light test (3 seconds). Let all three run in parallel with asyncio.gather. Afterwards asyncio.zeit() should give 3.0 – not 6.0 like one after another.

import asyncio


async def task(name, seconds):
    await asyncio.sleep(seconds)
    print(f"{name} done")


async def main():
    # start all three at the same time
    await task("Motor", 2)
    await task("Sensor", 1)
    await task("Light", 3)
    print("Total time:", asyncio.zeit())


asyncio.run(main())

Solve it without hints to earn a ⭐ on your progress page.

Show solution

Try it yourself first – mistakes teach you the most. Here is one possible solution:

import asyncio


async def task(name, seconds):
    await asyncio.sleep(seconds)
    print(f"{name} done")


async def main():
    # start all three at the same time
    await asyncio.gather(
        task("Motor", 2),
        task("Sensor", 1),
        task("Light", 3),
    )
    print("Total time:", asyncio.zeit())


asyncio.run(main())