动态setTimeout导致"超出最大调用堆栈"错误

时间:2016-12-28 01:52:24

标签: javascript node.js

我正在尝试创建将调用函数的setTimeout,然后函数将再次调用setTimeout但具有不同的间隔值。

问题在于它似乎陷入无限循环。

这些是起始变量:

var interval = 1500;
var elapsed = 0;
var totalTimer = 40000;
var startTime = null;

这是功能:

function playLights(){
        startTime = Date.now();
        interval = (totalTimer-elapsed) * 0.026;
        lights[0].color(0, 91, 68, 3500, 0);
        lights[1].color(0, 91, 68, 3500, 0);
        setTimeout(function(){
            lights[0].color(0, 100, 100, 3500, 0);
            lights[1].color(0, 100, 100, 3500, 0);
        }, 300);
        elapsed = Date.now() - startTime;
        if((Date.now() - startTime) < 37000){
            setTimeout(playLights(), interval.toFixed());
        }
        console.log("Interval: "+interval+" ,Elapsed: "+elapsed);
    }

当行动发生时,我致电playLights();

应该发生什么:

1)炸弹在游戏中种植,

2)必须调用playLights(),

3)必须获取当前时间并保存,

4)它必须确定间隔,因此,因为它是第一次呼叫 - 它必须是1040 ms。

5)它必须闪烁颜色。 (现在不重要)

6)然后它必须根据currentDate - storedDate计算经过的时间。

7)然后必须检查经过的时间是否超过37000毫秒(37秒)

如果是 - 自行设置setTimeout。

如果没有 - 只是没有。

我不断获得Node.js超出的最大调用堆栈

我是否在某个地方犯了错误,导致它陷入无限循环?

1 个答案:

答案 0 :(得分:2)

您的代码中存在多个错误,例如
 在您的功能中,您将startTime设置为Date.now()它没关系,但是!在下一刻,您将elapsed设置为Date.now() - startTime,因此它始终为0,因为startTime等于Date.now()。  然后你在if部分的陈述中做同样的事情,它将永远是真的。   所以基本上没什么变化,导致无限循环等。  您可以在主函数中设置startTime,也可以通过playLights()函数传递它。  最后,您必须将startTime传递给callback中的setTimeout()函数,您可以这样做:

`setTimeout(function() {playLights(startTime);}, interval.toFixed());`

所以你的代码看起来像这样:

function playLights(startTime) {
    interval = (totalTimer-elapsed) * 0.026;
    lights[0].color(0, 91, 68, 3500, 0);
    lights[1].color(0, 91, 68, 3500, 0);
    setTimeout(function() {
        lights[0].color(0, 100, 100, 3500, 0);
        lights[1].color(0, 100, 100, 3500, 0);
    }, 300);
    elapsed = Date.now() - startTime;
    if (elapsed < 37000) {
        setTimeout(function(){playLights(startTime)}, interval.toFixed());
    }
    console.log("Interval: "+interval+" ,Elapsed: "+elapsed);
}

你可以这样称呼它:

playLights(Date.now());