cycle
Yields a sequence, then repeats it — forever. Always pair it with a bound like take.
Lecture
cycle is infinite: it plays the source
sequence once, buffering its values as it goes, then loops over that
buffer forever. Unlike everything else in this section,
cycle never runs out on its own — you must always pair it
with something that decides when to stop, almost always
.take(n). Calling toList() or
consume() directly on a bare cycle(...)
without a bound in between will hang.
One edge case worth knowing: cycling an empty source yields
nothing at all, rather than looping forever over zero elements — so
cycle([]) is safe and simply produces an empty result.
It's a natural building block for round-robin assignment (cycle through
a small list of workers/colors/slots as you map over a longer one) or
for repeating a short async sequence to model a polling loop. The async
form, cycleAsync (or .cycle() on an
FxAsync chain), buffers and loops the same way, but pulls
each round through the usual async protocol.
Demo 1 · Infinite, bounded by take
Demo 2 · Async cycle, still bounded by take
Try it yourself
Exercise: cycle through traffic-light colors and take the first 8.
range — a finite counting sequence ·
repeat — repeat a single value, a fixed number of times ·
take — the bound cycle almost always needs ·
concurrent — overlap an async cycle's work