使用Express / Node.js和Angular处理取消的请求 [英] Handling cancelled request with Express/Node.js and Angular
问题描述
当客户端/浏览器取消挂起的HTTP请求时,Node Express继续处理请求。对于密集的请求,CPU仍然在忙于不必要的请求。
有没有办法要求Node.js / Express杀死/停止这些待处理的请求请求被取消?
由于AngularJS 1.5 HTTP请求很容易 $ cancelRequest() $ $ http $ c可以取消
的ngResource / service / $ resource =noreferrer $ c> / $ resource
对象。
当公开API方法时,可能会发生这种取消,完成或搜索字段:在字段中输入要自动完成或提前输入时,先前的请求可以被取消。
全局 server.timeout
不能解决问题:1)它是所有暴露的API方法的全局设置的先验2)取消的请求中正在进行的处理不会被终止。
注入 req
对象与侦听器一起发送 .on()
。
收听关闭
事件允许在客户端关闭连接时处理(请求由Angular取消,或者例如用户关闭查询选项卡) / p>
这里有两个简单的例子,如何使用关闭
事件来停止请求处理。
示例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 };
}
/ *处理项目* /
});
//在客户端取消请求之前完成的作业,将结果发送给客户端
res.send(/ * results * /);
} catch(e){
//重新抛出(或调用next(e))非取消异常
if(e.type!== clientCancelledRequest){
扔e
}
}
//在客户端取消请求之前完成的作业,将结果发送给客户
res.send(/ * results * /);
}
示例2:具有承诺的可取消异步块(类似于减少)
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};
}
/ *工作项目* /
});
});
promise.then(function(){
//在客户端取消请求之前完成的作业,将结果发送给客户
res.send(/ * results * /);
})
.catch(function(err){
//重新抛出(或调用next(err))对非取消异常
if(err.type!= = clientCancelledRequest){
throw err;
}
})
.done();
}
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 kept busy with unnecessary requests.
Is there a way to ask Node.js/Express to kill/stop these pending requests that are requested to be cancelled?
It becomes particularly useful given that since AngularJS 1.5 HTTP request are easily cancellable by calling $cancelRequest()
on $http
/$resource
objects.
Such cancellations could occur when exposing an API method providing results for auto-completion or search fields: when typing in the field to be autocompleted or type-aheaded, previous request(s) can be cancelled.
A global server.timeout
does not solve the problem: 1) it is a priori a global setting for all exposed API methods 2) ongoing processing in the canceled request is not killed.
Injected req
object 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 close
event 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();
}
这篇关于使用Express / Node.js和Angular处理取消的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!