When we write Connect middlewares that contain async operations, it is good practice to 'pause' the HTTP request with the help of the Connect utility function. When the async operation has finished, the HTTP request is resumed again. Let's have a look at the documentation for this utility:
Pause `data` and `end` events on the given `obj`.
Middleware performing async tasks _should_ utilize
this utility (or similar), to re-emit data once
the async operation has completed, otherwise these
events may be lost.
What this means is that during the time the HTTP request is paused, end
and data
events are buffered and immediately replayed when pauseControl.resume()
is called.
On to explaining WHY the order matters as when to resume the HTTP request:
// WRONG CODE!!!
var pause = utils.pause(req);
fs.readFile(path, function(){
pause.resume();
next();
});
The next
function invokes the next middleware on the stack of the Connect server. This next middleware may start listening to data
and end
events as well, which makes it likely that it would like to receive the buffered data
and end
events as well that were captured during the pause.
Since the resume()
is invoked BEFORE the next middleware, the data
and end
events have already been replayed, thus missed by the event listeners that will be set inside the next middleware.
The result is unexpected behavior for the middleware layers after this one, because there is a chance that the end
may not be emitted anymore, resulting in never-ending HTTP request (because the server will only start sending back the response when it received and parsed the request data).
So I blame you for the bug I introduced :)