Handling cancelled request with Express/Node.js and Angular

后端 未结 3 1637
深忆病人
深忆病人 2020-12-25 12:00

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

相关标签:
3条回答
  • 2020-12-25 12:22

    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();
    }
    
    0 讨论(0)
  • 2020-12-25 12:22

    With express, you can try:

    req.connection.on('close',function(){    
      // code to handle connection abort
      console.log('user cancelled');
    });
    
    0 讨论(0)
  • 2020-12-25 12:22

    You can set a timeout for requests on your server:

    var server = app.listen(app.get('port'), function() {
      debug('Express server listening on port ' + server.address().port);
    });
    // Set the timeout for a request to 1sec
    server.timeout = 1000;
    
    0 讨论(0)
提交回复
热议问题