Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中的第1个函数和第2个函数中的setTimeout()是否会出现堆栈溢出错误?_Javascript_Loops_Settimeout_Stack Overflow_Nested Loops - Fatal编程技术网

javascript中的第1个函数和第2个函数中的setTimeout()是否会出现堆栈溢出错误?

javascript中的第1个函数和第2个函数中的setTimeout()是否会出现堆栈溢出错误?,javascript,loops,settimeout,stack-overflow,nested-loops,Javascript,Loops,Settimeout,Stack Overflow,Nested Loops,经过一段时间的工作(经过几个小时的计算),是否可能出现堆栈溢出错误? 从长远来看,还是其他错误 var timerIdPrecalculationsTurns = null; function precalculationsInit() { if (!timerIdPrecalculationsTurns) { timerIdPrecalculationsTurns = setTimeout(function(){

经过一段时间的工作(经过几个小时的计算),是否可能出现堆栈溢出错误? 从长远来看,还是其他错误

    var timerIdPrecalculationsTurns = null;

    function precalculationsInit() {
        if (!timerIdPrecalculationsTurns) {
            timerIdPrecalculationsTurns = setTimeout(function(){
                precalculationsInitClosure();
            }, 10);
        }
    }

    function precalculationsInitClosure() {
        // make some calculations for ~20ms ...
        // and then repeat in next iteration:
        timerIdPrecalculationsTurns = null;
        precalculationsInit();
    }

    // just start the loop
    precalculationsInit();
这是我使用的简化版代码。但我希望这能说明我的问题

有一些类似的答案,但我不确定这是否也是我的情况:


您实现此功能的方式不应该有任何问题。我建议您在这个用例中使用setInterval

您实现它的方式不应该有任何问题。我建议您在本用例中使用setInterval

不,不会

计时器“搁置”回调-它们不会在与当前正在运行的回调相同的执行堆栈中调用它们(调用
setTimeout
)。JS将继续执行当前脚本,直到堆栈为空,然后再调用计时器设置的任何回调(或任何已完成的异步操作)

在您的情况下,
precalculationsInit
将“调度”
precalculationsInitClosure
,然后完成执行,清空堆栈。然后至少10分钟后,JS将调用预定的
precalculationsInitClosure
,执行一些操作,然后调用
precalculationsInit
,并重复相同的过程

您的堆栈如下所示:

(empty)
pI (schedules pIC)
(empty, JS looks for callbacks)
pIC
pIC -> pI (schedules pIC)
pIC
(empty, JS looks for callbacks)
pIC
pIC -> pI (schedules pIC)
pIC
(empty)
...and so on
如您所见,由于这种“调度”/“搁置”,堆栈不会像递归中那样构建:

pI
pI -> pIC
pI -> pIC -> pI
pI -> pIC -> pI -> pIC
...and so on
不,不会的

计时器“搁置”回调-它们不会在与当前正在运行的回调相同的执行堆栈中调用它们(调用
setTimeout
)。JS将继续执行当前脚本,直到堆栈为空,然后再调用计时器设置的任何回调(或任何已完成的异步操作)

在您的情况下,
precalculationsInit
将“调度”
precalculationsInitClosure
,然后完成执行,清空堆栈。然后至少10分钟后,JS将调用预定的
precalculationsInitClosure
,执行一些操作,然后调用
precalculationsInit
,并重复相同的过程

您的堆栈如下所示:

(empty)
pI (schedules pIC)
(empty, JS looks for callbacks)
pIC
pIC -> pI (schedules pIC)
pIC
(empty, JS looks for callbacks)
pIC
pIC -> pI (schedules pIC)
pIC
(empty)
...and so on
如您所见,由于这种“调度”/“搁置”,堆栈不会像递归中那样构建:

pI
pI -> pIC
pI -> pIC -> pI
pI -> pIC -> pI -> pIC
...and so on

是的,这些答案也适用于您的代码。你为什么认为这不一样?超时是在函数
precalculationsInitClosure
的“子例程”(subroutine)(
precalculationsInit
)中创建的,该函数是从(由调用的函数表达式)超时调用的,这无关紧要。是的,这些答案也适用于您的代码。你为什么认为这不一样?超时是在函数
precalculationsInitClosure
的“子例程”(subroutine)(
precalculationsInit
)中创建的,该函数从(由调用的函数表达式)调用超时无关紧要。如果没有问题,您为什么推荐其他内容-P@Bergi更干净更可读谢谢,但我的定期工作有不同的执行时间:10毫秒-150毫秒。所以间隔时间对我来说不是最好的。如果没有问题,你为什么要推荐其他东西呢-P@Bergi更干净更可读谢谢,但我的定期工作有不同的执行时间:10毫秒-150毫秒。所以我的情况不是最好的。谢谢。这是非常有用的解释。谢谢。这是非常有用的解释。