我在函数内调用 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
最佳答案
你的递归调用是
setTimeout(get_zone_counts, retry_delay, url);
这意味着:在 retry_delay
毫秒后调用 get_zone_counts
,参数为 url
。也就是说,retry_delay
不会传递给任何后续调用。
如果您想将与初始调用中相同的 retry_delay
传递给递归调用,请将其添加到 setTimeout
参数列表的末尾:
setTimeout(get_zone_counts, retry_delay, url, retry_delay);
这基本上是一样的
setTimeout(() => get_zone_counts(url, retry_delay), retry_delay);
这可能看起来更直观一些。
关于javascript - 为什么在后续使用setTimeout的调用中retry_interval未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51927330/