When a pending HTTP request is cancelled by a client/browser it seems that Node with Express continues to process the request. For intensive requests, the CPU is still being
Injected reqobject is shipped with listeners .on().
Listening to close event allows to handle when client close the connection (request cancelled by Angular or, e.g., user closed the querying tab).
Here are 2 simple examples how to use the closeevent to stop request processing.
Example 1: Cancellable synchronous block
var clientCancelledRequest = 'clientCancelledRequest';
function cancellableAPIMethodA(req, res, next) {
var cancelRequest = false;
req.on('close', function (err){
cancelRequest = true;
});
var superLargeArray = [/* ... */];
try {
// Long processing loop
superLargeArray.forEach(function (item) {
if (cancelRequest) {
throw {type: clientCancelledRequest};
}
/* Work on item */
});
// Job done before client cancelled the request, send result to client
res.send(/* results */);
} catch (e) {
// Re-throw (or call next(e)) on non-cancellation exception
if (e.type !== clientCancelledRequest) {
throw e;
}
}
// Job done before client cancelled the request, send result to client
res.send(/* results */);
}
Example 2: Cancellable asynchronous block with promises (analog to a reduce)
function cancellableAPIMethodA(req, res, next) {
var cancelRequest = false;
req.on('close', function (err){
cancelRequest = true;
});
var superLargeArray = [/* ... */];
var promise = Q.when();
superLargeArray.forEach(function (item) {
promise = promise.then(function() {
if (cancelRequest) {
throw {type: clientCancelledRequest};
}
/* Work on item */
});
});
promise.then(function() {
// Job done before client cancelled the request, send result to client
res.send(/* results */);
})
.catch(function(err) {
// Re-throw (or call next(err)) on non-cancellation exception
if (err.type !== clientCancelledRequest) {
throw err;
}
})
.done();
}