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

新手上路,请多包涵

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

有没有办法让 Node.js/Express 杀死/停止这些请求取消的待处理请求?

它变得特别有用,因为 AngularJS 1.5 HTTP 请求可以通过调用 $cancelRequest()$http / $resource 上轻松 取消

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

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

原文由 Derek 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 944
2 个回答

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

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

以下是如何使用 close 事件停止请求处理的 2 个简单示例。

示例 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:带有 promises 的可取消异步块(类似于 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();
}

原文由 Derek 发布,翻译遵循 CC BY-SA 3.0 许可协议

使用快递,您可以尝试:

 req.connection.on('close',function(){
  // code to handle connection abort
  console.log('user cancelled');
});

原文由 Hank Phung 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏