We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Synchronous vs. Asynchronous

Most of the Python you've written so far is synchronous – each line runs only after the one above finishes.

print("I print first")
print("I print second")
print("I print third")

In asynchronous or async code, long-running operations (e.g. HTTP requests, timers) can pause one task while the program keeps doing something else. Python ships the asyncio library for this:

import asyncio


async def delay_print(ms: int, text: str) -> None:
    await asyncio.sleep(ms / 1_000)
    print(text)


async def main() -> None:
    print("I print first")
    asyncio.create_task(delay_print(100, "I print third after 100 ms"))
    print("I print second")
    await asyncio.sleep(0.2)  # keep the loop alive briefly


await main()  # Pyodide already has a running event loop
# asyncio.run(main()) - how you'd normally do it

Top-level awaits aren't normally allowed in Python. Pyodide – our WASM Python runner – uses the browser's event loop which is already running, so calling asyncio.run will raise an error.

Assignment

To help us visualize how asynchronous code executes, let's practice with an example from Jello.

Update the waiting durations so that text is printed in the following order:

  1. Starting project initialization...
  2. Creating project repository...
  3. Setting up continuous integration...
  4. Configuring project boards...
  5. Project setup complete!

You wouldn't normally change the order in which text is printed to the console this way, but it's a good way for us to practice async code.