Async
Everything at once
Mapping over a list with Promise.all, and what happens when the list is longer than the thing at the other end can take.
12 minutes · backpressure · concurrency limits · semaphores
Promise.all is not a loop
`await Promise.all(items.map(handle))` starts every one of them immediately. With four items that is fine. With four thousand it is a self-inflicted denial of service on whatever is at the other end, and the failure arrives as rate-limit errors or timeouts that look like somebody else's fault.
The fix is a limit, and a limit is a semaphore: a fixed number of permits, taken before the work and given back after. What makes it interesting is that the limit has to hold across every concurrent caller, which means the counting has to be right under interleaving.