一尘不染

使用Express / Node.js和Angular处理已取消的请求

angularjs

当客户端/浏览器取消了挂起的HTTP请求时,带有Express的Node似乎继续处理该请求。对于密集请求,CPU仍然忙于处理不必要的请求。

有没有办法让Node.js / Express杀死/停止这些被要求取消的未决请求?

它给出的是,由于AngularJS 1.5
HTTP请求是容易变得特别有用的撤销通过调用$cancelRequest()$http/
$resource对象。

当暴露提供自动完成或搜索字段结果的API方法时,可能会发生此类取消:在要自动完成或提前输入的字段中键入内容时,可以取消以前的请求。

全局server.timeout不能解决问题:1)它是所有公开的API方法的先验全局设置2)被取消的请求中正在进行的处理不会被杀死。


阅读 315

收藏
2020-07-04

共1个答案

一尘不染

注入的req对象随侦听器一起提供.on()

侦听close事件允许处理客户端关闭连接的时间(Angular取消了请求,或者例如用户关闭了查询选项卡)。

这是两个简单的示例,说明如何使用close事件停止请求处理。

示例1:可取消同步块

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 */);
}

示例2:带有promise的可取消异步块(模拟为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();
}
2020-07-04