- Couldn't it be simpler without the linked-list queue? Use an array: the first ndispatched are for calls that have been invoked; they each hold either the corresponding result or undefined if not yet resolved by their callback. The rest of the array holds arguments objects for pending calls. When it's time to notify, this array is the results array.
- The 2-space indent plus fairly deep nesting makes it hard to see where the 'main story' starts and ends, at least for me. 4-space indent goes better with this nested style.
Some doc suggestions from my draft and I'll finally shut up:
// Can you call things after the first .await or .awaitAll?
// Whatever the answer, it should be documented.
// Maybe document the assumption that callbacks get invoked exactly once?
// (It'd be possible to ensure it's at most once.)
// Document assumption: the notified awaitAll function won't mess with its array argument
// (this matters if we're called again after).OTOH if the loop only ever pops at most one deferral, then an if instead of a while would make this clear.
Popping multiple synchronous tasks after an asynchronous one is fairly rare, but I’ll make sure the tests verify this code path.