如何修复JavaScript中的settimeout内存泄漏问题

时间:2019-05-06 01:00:18

标签: javascript memory-leaks settimeout

我有这样的JS函数

function check() {
    ...do something
}

现在,我想在脚本启动时以及每天(每天00:00:01)开始时运行它。我的代码现在看起来像这样

function check() {
    ...do something

    let today = new Date();
    let tomorrow = new Date();
        tomorrow.setHours(0,0,1,0);
        tomorrow.setDate(tomorrow.getDate()+1);

    console.log("next check in", tomorrow-today);
    setTimeout(() => { check() }, tomorrow-today);
}
check();

我在check()中使用setTimeout。我认为这是不好的代码,因为它将创建一个循环,并且函数check()将永远不会被清理。如何解决?

2 个答案:

答案 0 :(得分:2)

您是正确的,由于堆栈无限期地增长,不受控制的递归可能导致资源耗尽。例如,下面的Javascript程序将在执行check()而没有首先进行return的次数之后崩溃:

function check() {
  check();
}
check();

以下代码不会以这种方式崩溃:

function check() {
  setTimeout(check, 1000);
}
check();

该代码可以无限期地运行而不会耗尽堆栈,因为每次运行check()时,它都可以运行完成,而return则可以在以后运行。

之所以可行,是因为setTimeout()函数不能直接运行check()。相反,它告诉Javascript运行时将check()的执行安排在未来1秒钟。当它和check()完成时,Javascript堆栈将为空。 1秒钟后,只要清除了Javascript堆栈,就将check()的执行排队并最终执行。

由于必须先清除Javascript堆栈,然后才能运行check(),因此可以避免堆栈溢出。

答案 1 :(得分:0)

您可以添加函数clearTimeout(timer):

let timer = setTimeout(() => check());

clearTimeout(timer);