doneWaiting throws on the first rejected promise that it encounters. This means that subsequent rejected promises may result in unhandled rejection errors.
Fixes#3171
* Fix NetworkFirst waitUntil
NetworkFirst's design uses two promises (one for the network request, and one for the timeout). If the network request succeeds, then the timeout promise's timer is canceled. However, it attempted to wait until both promises were done before marking the event as done; this meant that, if the network request succeeded, then it never resolved its handlerDone / awaitComplete promise.
This fixes#2721.
* Add a test to cover the timeout-not-exceeded case
* Explicitly verify that the promise resolved before timeout
* Properly handle network fallback
Improve typings for waitUntil; since the revised logic uses a callback, it can't rely on type inference as much.
* Code review feedback
Follow coding style; remove eventDoneWaiting calls, since that duplicates donePromise.