Skip to content

How does a loop await a sequence of values that arrive over time?

Level: 201 · anyone who wants for over a channel in async code

Stub — a question and its expected answers, not yet a lesson. No program behind this page has been written or run, so nothing on it has been through the check that backs every finished page. The table is what the finished lesson is expected to find, and every cell is unverified until a program prints it. (Not machine-checked here.)

One line: An async stream is an iterator whose next is awaited — the values arrive over time and the loop yields between them — and it is where the languages' async designs are furthest apart: Python has async for, Rust has a Stream trait outside the standard library, Go has a channel and needs nothing else, and Java has Flow.Publisher with request-N backpressure.

The question

A source produces a value every 100 ms, ten times. A consumer loops over them, awaiting each. The page writes the source and the loop in each language and confirms the ten values arrived in order, then asks the stream's two hard questions: what happens when the consumer is slower than the source, and how the loop ends.

What each language is expected to say

Expected answer, to be verified by the program
Rust no Stream in std; futures::Stream and while let Some(x) = s.next().await (link, not run); the std column uses a channel on a thread
Go for x := range ch over a channel fed by a goroutine
C a read loop on a pipe
C++ a C++20 generator-style coroutine, hand-rolled promise type; std::generator is C++23
Java Flow.Publisher and a Subscriber calling request(1)
Python async for x in agen() over an async def with yield

What the programs have to show

  • ten values at 100 ms intervals, received in order
  • the slow consumer: the source waits (backpressure) or runs ahead, per design
  • the end: the generator returning, the channel closing, onComplete

See also