Checking Array.fromAsync support…
Array.fromAsyncsequential
0 mstotal = sum
await Array.fromAsync( tasks, t => t() ); // each awaits the previous
Promise.allparallel
0 mstotal = slowest
await Promise.all( tasks.map(t => t()) ); // all fire at once
Promise.all can't do this. A paginated API modelled as an async generator doesn't know its length upfront. Array.fromAsync walks it lazily, collecting every item across every page into one array.
async function* fetchAllPages(url) { let next = url; while (next) { const page = await fetch(next).then(r => r.json()); for (const item of page.items) yield item; next = page.nextPage; // null when done } } const all = await Array.fromAsync(fetchAllPages('/api/products'));
idle — 0 items collected
// items appear here as each page arrives…
Two gotchas that bite in production. Sequential naturally throttles a rate-limited API; parallel hammers it. And Array.fromAsync always returns a Promise — forget await and you get the wrong type.
Rate-limit simulator (API allows 2 concurrent)
// fire requests and watch for 429s…
The forgotten-await gotcha
❌ Missing await
Array.fromAsync(gen())
// —
✅ With await
await Array.fromAsync(gen())
// —