我在函数中调用setTimeout遇到问题。 setTimeout递归调用get_zone_counts函数(仅在错误情况下)。第一次调用setTimeout时,根据函数的第一次调用正确设置了retry_delay参数。但是在随后的setTimeout调用中,retry_delay参数是不确定的。
为什么会这样,我该如何解决?
代码如下:
const request = require('request');
// server not connected for this test
const url = "http://192.168.1.23/api/data/live?format=JSON";
function handle_zone_count_response(body, container) {
// this function simply parses the response message
console.log("handle_zone_count_response called");
}
function get_zone_counts(url, retry_delay) {
request.get(url, function(error, res, body) {
if(error) {
console.log("error: ", error);
console.log(`setting timer to retry zone count requests in ${retry_delay} msecs`);
// set timer to try again after retry_delay
setTimeout(get_zone_counts, retry_delay, url);
} else {
console.log(body);
handle_zone_count_response(body, zone_counts);
// print zone_counts
console.log("zone counts: ", zone_counts);
}
});
}
get_zone_counts(url, 5000);
示例输出:
error: { Error: connect ETIMEDOUT 192.168.1.23:80
at Object._errnoException (util.js:1003:13)
at _exceptionWithHostPort (util.js:1024:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1195:14)
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
address: '192.168.1.23',
port: 80 }
setting timer to retry zone count requests in 5000 msecs
error: { Error: connect ETIMEDOUT 192.168.1.23:80
at Object._errnoException (util.js:1003:13)
at _exceptionWithHostPort (util.js:1024:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1195:14)
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
address: '192.168.1.23',
port: 80 }
setting timer to retry zone count requests in undefined msecs
error: { Error: connect ETIMEDOUT 192.168.1.23:80
at Object._errnoException (util.js:1003:13)
at _exceptionWithHostPort (util.js:1024:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1195:14)
errno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
address: '192.168.1.23',
port: 80 }
setting timer to retry zone count requests in undefined msecs
答案 0 :(得分:3)
您的递归调用是
setTimeout(get_zone_counts, retry_delay, url);
这意味着:在get_zone_counts
毫秒后使用参数retry_delay
调用url
。也就是说,retry_delay
不会传递到任何后续调用。
如果要将与初始调用相同的retry_delay
传递给递归调用,请将其添加到setTimeout
参数列表的末尾:
setTimeout(get_zone_counts, retry_delay, url, retry_delay);
这基本上与
相同setTimeout(() => get_zone_counts(url, retry_delay), retry_delay);
看起来更直观。