简体   繁体   English

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

[英]How to fix settimeout memory leak problem in javascript

I have a JS function like this 我有这样的JS功能

function check() {
    ...do something
}

Now, I want to run it when script start, and at start of everyday (00:00:01 everyday). 现在,我想在脚本启动时以及每天(每天00:00:01)开始时运行它。 My code now look like this 我的代码现在看起来像这样

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();

I'm using setTimeout inside check(). 我在check()中使用setTimeout。 I think it's bad code because it will create a loop, and function check() will never been cleanup. 我认为这是不好的代码,因为它将创建一个循环,并且函数check()将永远不会被清理。 How to fix it ? 如何解决?

You are right that uncontrolled recursion could cause exhaustion of resources due to the stack growing indefinitely. 没错,由于堆栈无限期增长,不受控制的递归可能导致资源耗尽。 For example, the following Javascript program will crash after check() is executed sufficient times without first return ing: 例如,以下的Javascript程序将在执行check()足够多次而没有先return情况下崩溃:

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

The following code will not crash in this way: 以下代码不会以这种方式崩溃:

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

This code can run indefinitely without exhausting the stack because each time check() is run, it is allowed to run to completion and return before it is run in the future. 该代码可以无限期地运行而不会耗尽堆栈,因为每次运行check() ,它都允许运行至完成并在以后运行之前return

This works because the setTimeout() function doesn't directly run check() . 之所以可行,是因为setTimeout()函数不会直接运行check() Instead, it tells the Javascript runtime to schedule an execution of check() for 1s into the future. 相反,它告诉Javascript运行时将check()的执行安排在将来执行1秒。 When it and check() have completed, the Javascript stack becomes empty. 当它和check()完成时,JavaScript堆栈变为空。 1s later, the execution of check() is queued and eventually executed as long as the Javascript stack is clear. 1s之后,只要清除了Javascript堆栈, check()的执行就会排队,并最终执行

Since the Javascript stack must be clear before check() can run, stack overflows are avoided. 由于必须在运行check()之前清除Javascript堆栈,所以可以避免堆栈溢出。

You could add the function clearTimeout(timer): 您可以添加函数clearTimeout(timer):

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

clearTimeout(timer);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM