consume

Pulls values through a chain and throws them away — for side effects only, optionally capped.

void consume<A>(Iterable<A> iterable, [int? n]) Future<void> consumeAsync<A>(FxAsyncIterable<A> iterable, [int? n]) void Fx.consume([int? n]) // chain Future<void> FxAsync.consume([int? n])

Lecture

consume is the minimal terminal operator: it pulls values through the chain — running whatever peek or mapEffect steps are upstream for their side effects — but discards every value instead of collecting or forwarding it. Reach for it when the whole point of a pipeline is its side effects, and building a List with toList would just be wasted allocation.

The optional n makes it the natural partner for infinite or huge sources: consume(5) pulls exactly 5 values and stops, even if the underlying iterable (range with no bound, cycle, repeat with a huge count) would otherwise go on forever. Omit n to drain a finite iterable completely.

consumeAsync (or .consume() on an FxAsync chain) works the same way, awaiting each pulled value's side effects in turn — handy for forcing an async peek/logging pipeline to actually run without paying to collect a result list you'd throw away anyway.

Demo 1 · Bounding an infinite source

range(1000000) would normally never finish if fully pulled — but consume(5) stops after 5 elements:

Demo 2 · Async side effects, no result list

Try it yourself

Exercise: consume only the first 3 values of an effectively-infinite repeat(), logging each one as it's pulled.

Related: each — terminal op that also runs f, without the n-limit shortcut · toList — terminal op that collects results instead · cycle — an infinite source consume is often paired with · peek — the lazy side-effect step consume typically forces