javascript - 为什么在后续使用setTimeout的调用中retry_interval未定义

标签 javascript scope

我在函数内调用 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/

相关文章:

javascript - 如何使用 angular cli 默认试运行

perl - 为什么 $main::_ 在映射或 for 循环中使用时引用词法 $_?

java - 如果我调用静态方法,构造函数是否运行

C 数组错误 - 要求我声明同一个变量两次

javascript - 在 MVC 中使用 jquery 突出显示搜索词

javascript - ajax 请求后的 Chrome window.open 就像弹出窗口一样

javascript - 为什么我的 Meteor 应用程序无法识别我的功能?

使用 reduce 的 Javascript 重构映射示例

javascript - 为 JavaScript for 循环重用 "i"

scope - 当声明符(我的/状态)在 for block 中时会发生什么?