如何让Node.js的http请求支持超时

 我来答
育知同创教育
2017-08-02 · 百度知道合伙人官方认证企业
育知同创教育
1【专注:Python+人工智能|Java大数据|HTML5培训】 2【免费提供名师直播课堂、公开课及视频教程】 3【地址:北京市昌平区三旗百汇物美大卖场2层,微信公众号:yuzhitc】
向TA提问
展开全部
Node.js的http模块可用非常方便地请求网络资源,但是它不支持超时,这个挺不方便的;因为有些网络资源可能突然不可用了,我们不能等到系统自动超时才去做一些处理。实现一个也挺容易的,如下:

function requestWithTimeout(options,timeout,callback){
var timeoutEventId,
req=http.request(options,function(res){

res.on('end',function(){
clearTimeout(timeoutEventId);
console.log('response end...');
});

res.on('close',function(){
clearTimeout(timeoutEventId);
console.log('response close...');
});

res.on('abort',function(){
console.log('abort...');
});

callback(res);
});

req.on('timeout',function(e){
if(req.res){
req.res('abort');
}
req.abort();
});

timeoutEventId=setTimeout(function(){
req.emit('timeout',{message:'have been timeout...'});
},timeout);

return req;
}

我们可用这样来调用requestWithTimeout方法:

var http=require('http');
var options = {
host: 'dict.youdao.com',
port: 80,
method: 'GET'
};
var req=requestWithTimeout(options,4000,function(res){
res.on('data',function(chunk){
console.log('body:'+chunk);
});
});

req.on('error',function(e){
console.log('error got :' + e.message);
}).on('timeout',function(e){
console.log('timeout got :'+ e.message);
});

req.end();

代码比较简单,也能很好地处理超时,但是,重新定义一个方法显得不怎么好,能否让http.request方法直接支持timeout呢?也就是说,直接在options参数中支持timeout属性。我们可用重写http.request方法,如下:

http.request=(function(_request){
return function(options,callback){
var timeout=options['timeout'],
timeoutEventId;
var req=_request(options,function(res){
res.on('end',function(){
clearTimeout(timeoutEventId);
console.log('response end...');
});

res.on('close',function(){
clearTimeout(timeoutEventId);
console.log('response close...');
});

res.on('abort',function(){
console.log('abort...');
});

callback(res);
});

//超时
req.on('timeout',function(){
req.res && req.res.abort();
req.abort();
});

//如果存在超时
timeout && (timeoutEventId=setTimeout(function(){
req.emit('timeout',{message:'have been timeout...'});
},timeout));
return req;
};

})(http.request)

调用就更直观了,和普通的request调用没啥区别,只是传入的options中多了timeout属性。

var http=require('http');
var options = {
host: 'dict.youdao.com',
port: 80,
method: 'GET',
timeout:3000
};

var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});

req.on('error',function(e){
console.log("error got :"+e.message);
}).on('timeout',function(e){

console.log('timeout got :'+e.message);
});

req.end();

这样,我们就让http请求支持超时了。
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式