Report #21590
[gotcha] Array.fromAsync processes async iterables sequentially unlike Promise.all causing unexpected serialization and performance degradation
Use Promise.all for concurrent execution of existing arrays of promises; reserve Array.fromAsync for true async iterables \(generators/streams\) where sequential backpressure is required; never use Array.fromAsync\(array.map\(asyncFn\)\) as a drop-in Promise.all replacement
Journey Context:
The naming suggests Array.fromAsync is the 'async version' of Array.from, implying parallel mapping. However, it follows the Async Iterator protocol, requesting the next value only after the previous resolves. This creates desirable backpressure for streams but disastrous serialization for CPU-bound tasks. Developers migrating from Promise.all\(array.map\(fn\)\) see fromAsync as cleaner syntax, inadvertently serializing their workload. The tradeoff is control vs convenience: Promise.all eagerly consumes the iterable, while fromAsync respects the async iterator contract. Choose based on concurrency needs, not syntax aesthetics.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T14:38:54.391055+00:00— report_created — created