如何用nodejs处理超时请求

所以,我向服务器发出这个请求,我设置了一个超时,我想处理超时事件,但是我也想处理“中止”事件,并且不同的事件。 我设法做到这一点,但我想知道是否有更好的方法来做到这一点。 代码如下所示:

makeRequest = function(json, cb){ var requestError request({ url: REQUEST_URL, json: json, timeout: 3000, headers: { 'Content-Type': 'application/json' } }, function(err, res, body){ if(err) requestError = err else cb(null, res, body) }).on('abort', function(){ setTimeout(function({ if(requestError != 'ETIMEDOUT') cb(httpStatusCode.REQUEST_TIMEDOUT) else cb(httpStatusCode.REQUEST_ABORTED }, 1000) }) } 

我注意到,在超时事件中,'abort'事件都被触发,请求callback被调用,所以我使用setTimeout函数等待请求callback,并处理'abort'监听器中的错误。 这似乎是一个愚蠢的做法,我在网上search,并没有find一种方式哟只处理callback事件。 我也注意到,超时会触发on。('error',function(err){})事件,我可以处理这个错误,但是它也会调用on('abort',function(){})事件并最终调用主callback(CB)两次,崩溃我的应用程序。

有没有办法,我可以只有一个事件超时,只有一个中止,所以我不必使用setTimeout?

或者,我的req对象中是否有任何属性可以检查该请求是否超时?

或者你有什么其他的build议来解决我的问题,而不是丑陋的方式?

我正在使用nodejs 0.12.2和请求2.55.0谢谢!

关于开源的一个好处就是你可以随时查看模块的代码,看看它是如何工作的。

如果你想要这个错误,那么只要听.on('error', function(err) {}) 。 错误将被传递到那里。 .on('abort', function() {})事件不会告诉你为什么中止。 但是,从请求模块的相关源代码中可以看到, error事件总是在abort事件之后立即发送,并且将e.code设置为ETIMEDOUT

以下是调用.abort()的一些相关源代码的副本,您可以在其中看到它随后触发错误事件:

  if (self.timeout && !self.timeoutTimer) { var timeout = self.timeout < 0 ? 0 : self.timeout self.timeoutTimer = setTimeout(function () { self.abort() var e = new Error('ETIMEDOUT') e.code = 'ETIMEDOUT' self.emit('error', e) }, timeout) // Set additional timeout on socket - in case if remote // server freeze after sending headers if (self.req.setTimeout) { // only works on node 0.6+ self.req.setTimeout(timeout, function () { if (self.req) { self.req.abort() var e = new Error('ESOCKETTIMEDOUT') e.code = 'ESOCKETTIMEDOUT' self.emit('error', e) } }) } } 

所以,看起来你可以忽略abort事件,只听error事件,只是在error事件上调用你的callback。

如果你的代码是这样的,如果这个callback被错误地调用了多次(这听起来像是这样),那么你可以改变你的makeRequest()函数,这样它就不会多次调用callback。