如何让Node.js的http请求支持超时
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请求支持超时了。
http://www.cnblogs.com/flyingzl/articles/2286738.html