Asynchronous programming lets independent work continue without waiting for another operation to return. Unlike blocking execution, it can accept results as they become available, so completion order may be nondeterministic. section 8.2 section 8.3
A practical asynchronous workflow uses these steps:
- Mark operations that may wait with async, allowing them to return later. section 8.3
- Schedule several operations together instead of waiting for each one sequentially. section 8.3
- Await a gather operation so all results are collected before the application exits. section 8.3
- Measure the refactoring: eight Mandelbrot images improved from about 46 seconds to about 42 seconds locally. section 8.2 section 8.3
Mandelbrot image generation
A synchronous loop creates each image in order. Replacing the function and entry point with async definitions, scheduling the eight calls through asyncio.gather, and running main with asyncio.run allows images to finish in availability order. Adding randomized sleeps makes the behavior visible: images such as 1.png and 4.png can complete before 0.png. section 8.2 section 8.3
Asynchronous search
A Rust function can asynchronously fetch paginated search results, await the HTTP response and its text, parse XML into JSON-compatible structures, and verify the result with a unit test. section 9.3.1
Listing 8.5 main.py: Using async and asyncio
from PIL import Image
import asyncio #1
async def mandelbrot_func( #2
size: int,
path: str,
range_x0: float,
range_y0: float,
range_x1: float,
range_y1: float):
...
async def main(): #3
await asyncio.gather(*[ #4
mandelbrot_func(1000, f"{i}.png", -5.0, -2.12, -2.5, 1.12)
for i in range(0,8)
])
asyncio.run(main()) #5
Use the complete asyncio listing to inspect async function definitions, task gathering, and application startup together. section 8.3



























