如何使用nodejs处理请求超时
How to handle timeout using request with nodejs
因此,我正在向服务器发出此请求并设置了超时,我想处理超时事件,但我也想处理 'abort' 事件并且各不相同。我设法通过快速修复来做到这一点,但我想知道是否有更好的方法来做到这一点。代码如下所示:
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'事件被触发,请求回调被调用,按照这个顺序,所以我使用 setTimeout 函数来等待请求回调而不是处理错误在 'abort' 监听器中。这似乎是一种愚蠢的方法,我在网上搜索并没有找到只处理回调事件的方法。我还注意到超时触发了 on.('error', function(err){}) 事件,我可以在其中处理错误,但它也会调用 on.('abort', function() {}) 事件,我最终调用了主回调 (cb) 两次,导致我的应用程序崩溃。
有没有一种方法可以只为超时设置一个事件,而只为中止设置一个事件,这样我就不必使用 setTimeout?
或者我的请求对象中是否有任何 属性 我可以检查该请求是否超时?
或者您有任何其他建议以不那么丑陋的方式解决我的问题吗?
我正在使用 nodejs 0.12.2 并请求 2.55.0
谢谢!
开源的一大优点是您可以随时查看模块的代码,看看它是如何工作的。
如果你想要错误,那么只听 .on('error', function(err) {})
。错误将传递到那里。 .on('abort', function() {})
事件不会告诉您它被中止的原因。但是,正如您从请求模块的 relevant source code 中看到的那样,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
事件上调用回调。
如果你的代码是这样的,如果多次调用回调时出现错误(听起来确实如此),那么你可以更改你的 makeRequest()
函数,使其永远不会调用回调也不止一次。
因此,我正在向服务器发出此请求并设置了超时,我想处理超时事件,但我也想处理 'abort' 事件并且各不相同。我设法通过快速修复来做到这一点,但我想知道是否有更好的方法来做到这一点。代码如下所示:
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'事件被触发,请求回调被调用,按照这个顺序,所以我使用 setTimeout 函数来等待请求回调而不是处理错误在 'abort' 监听器中。这似乎是一种愚蠢的方法,我在网上搜索并没有找到只处理回调事件的方法。我还注意到超时触发了 on.('error', function(err){}) 事件,我可以在其中处理错误,但它也会调用 on.('abort', function() {}) 事件,我最终调用了主回调 (cb) 两次,导致我的应用程序崩溃。
有没有一种方法可以只为超时设置一个事件,而只为中止设置一个事件,这样我就不必使用 setTimeout?
或者我的请求对象中是否有任何 属性 我可以检查该请求是否超时?
或者您有任何其他建议以不那么丑陋的方式解决我的问题吗?
我正在使用 nodejs 0.12.2 并请求 2.55.0 谢谢!
开源的一大优点是您可以随时查看模块的代码,看看它是如何工作的。
如果你想要错误,那么只听 .on('error', function(err) {})
。错误将传递到那里。 .on('abort', function() {})
事件不会告诉您它被中止的原因。但是,正如您从请求模块的 relevant source code 中看到的那样,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
事件上调用回调。
如果你的代码是这样的,如果多次调用回调时出现错误(听起来确实如此),那么你可以更改你的 makeRequest()
函数,使其永远不会调用回调也不止一次。