mapConcurrent

Map with a concurrency limit in one step — toAsync().map(f).concurrent(n), pre-combined.

FxAsyncIterable<B> mapConcurrent<A, B>(int concurrency, FutureOr<B> Function(A a) f, Iterable<A> iterable) FxAsyncIterable<B> mapConcurrentAsync<A, B>(int concurrency, FutureOr<B> Function(A a) f, FxAsyncIterable<A> iterable) FxAsync<R> Fx<T>.mapConcurrent<R>(int concurrency, FutureOr<R> Function(T a) f) // chain (sync source) FxAsync<R> FxAsync<T>.mapConcurrent<R>(int concurrency, FutureOr<R> Function(T a) f) // chain (async source)

Lecture

"Run this async function over these values, at most n at a time, results in order" is the single most common async pipeline in real code — and until now it took three operators to say: toAsync() to enter the async world, map(f) to transform, and concurrent(n) to bound the evaluation. mapConcurrent(n, f) is that exact composition as one chain step.

Because it is the composition — not a reimplementation — every guarantee carries over: results arrive in source order (use concurrentPool behavior via the long form when you want completion order), at most concurrency callbacks are in flight, and downstream operators keep pulling lazily. On an already-async chain it composes map(f).concurrent(n), skipping the bridge.

This is a Dart-native addition: FxTS pipes concurrent as a separate step, and that long form remains available whenever you need to slot another operator between the map and the limit.

Demo 1 · Bounded fan-out, ordered results

Demo 2 · It is exactly map + concurrent

Try it yourself

Exercise: fetch every user two at a time, keeping the order.

Related: concurrent — the underlying limiter · concurrentPool — completion order instead of source order · toAsync — the sync→async bridge this absorbs · concurrent or parallel — I/O vs CPU