无限循环,而没有明显的原因

时间:2015-09-08 17:35:44

标签: javascript jquery html while-loop infinite-loop

我正在研究一个计时器,经过我在这个论坛得到的一些答案之后,它一直都很顺利。这就是它现在的样子:(只是为了让你明白这一点)

enter image description here

我的代码(请注意,这是一项正在进行中的工作,因此有些内容尚未完成;基本上每个具有alert("workin");的函数仍未使用。



<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>

<html>

<head>

<title>WIP</title>
<meta charset="UFT-8">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>


<script>

$(document).ready(function() {
	timerSet(9,12);
	timerRun();
});

function timerReset() {
	alert("workin");
}

function timerSet(inputMinutes, inputSeconds) {
	minutes = inputMinutes;	
	seconds = inputSeconds;	
	finalTimeInSeconds = minutes*60 + seconds; //finalTimeInSeconds is the time it takes for the timer to be 00:00 in seconds.
	timerPrint();
}

function timerAdd(inputMinutes, inputSeconds) {
	alert("workin");
}

function timerSubtract(inputMinutes, inputSeconds) {
	setTimeout(function () {
		if(minutes > 0 && seconds == 0) {
			minutes--;
			seconds = 59;
		} else {
			seconds--;
		}
		timerPrint();
	}, 1000);
}

function timerRun() {
	timerSubtract();
}

function timerStop() {
	alert("workin");
}

function timerPrint() {
	displayMinutes = (minutes.toString().length == 2) ? minutes : "0" + minutes;	//ternary operator: adds a zero to the beggining 
	displaySeconds = (seconds.toString().length == 2) ? seconds : "0" + seconds;	//of the number if it has only one caracter.
	$("#timerText").text(displayMinutes + ":" + displaySeconds);
}

function totalTime() {
	var totalTimeInSeconds = minutes*60 + seconds;

	return totalTimeInSeconds; //totalTimeInSeconds is the time that the timer now displays in seconds.
}

</script>

</head>

<body>

<div id="timerText">00:00</div>

</body>

</html>
&#13;
&#13;
&#13;

所以这是我的问题:在timerRun()函数中,我希望timerSubtract()函数在totalTime() > 0时重复,但如果我使用while循环,页面就会崩溃。为什么这样做?我不认为这是一个无限循环。我该怎么做才能想要?

感谢无论谁回答! : - )

4 个答案:

答案 0 :(得分:6)

问题在于timerSubtract使用setTimeout进行了工作。

每次使用setTimeout时,您都可以想象它会暂时搁置该功能。然后,一旦程序没有做任何事情(如果已经过了足够的时间),那么它将运行下一个被搁置的功能。通过运行while循环,您永远不会让运行时有机会使用setTimeout运行您的函数。

在使用setTimeout时解决此问题的一种方法是执行以下操作:

function timerRun() {
    if (minutes > 0 && seconds == 0) {
        minutes--;
        seconds = 59;
    } else {
        seconds--;
    }
    timerPrint();
    // Queue up timerRun to run again in 1 second
    setTimeout(timerRun, 1000);
}
timerRun();

答案 1 :(得分:2)

为什么不使用setInterval:

而不是使用setTimeout

http://jsfiddle.net/ouL1yzpq/

setInterval(function () {
    if(minutes > 0 && seconds == 0) {
        minutes--;
        seconds = 59;
    } else {
        seconds--;
    }
    timerPrint();
}, 1000);

选中此项以了解如何停止计时器:how to stop "setInterval"

答案 2 :(得分:0)

timerSubtract函数不会更改变量minutesseconds。它只会启动一个超时,以便稍后更改变量。

如果在循环中运行函数等待变量更改,那么变量将永远不会有任何变化。 JavaScript是单线程的,因此您必须退出该函数并将控件返回到浏览器以执行超时。循环运行时,不会处理超时事件。

如果JavaScript是多线程的,那么你的循环将启动数百万次超时,直到一秒钟过去并且超时将开始执行。由于您没有每秒启动超时但速度尽可能快,因此当时计时器会立即倒数至数百万。

setInterval中使用单个timerSubtract,而不是启动大量超时,而只调用该函数一次。间隔将每秒倒计时一次,因为我怀疑你的计时器是如何工作的:

function timerSubtract(inputMinutes, inputSeconds) {
    setInterval(function () {
        if(minutes > 0 && seconds == 0) {
            minutes--;
            seconds = 59;
        } else {
            seconds--;
        }
        timerPrint();
    }, 1000);
}

function timerRun() {
    timerSubtract();
}

答案 3 :(得分:0)

正如Jonathan发布的那样,您可以使用setInterval。我会在他的答案中添加clearInterval()来停止在0(这是你想要的吗?) 像这样:

function timerSubtract(inputMinutes, inputSeconds) {
    var countdown = setInterval(function () {
        if(minutes > 0 && seconds == 0) {
            minutes--;
            seconds = 59;
        } else {
            seconds--;
        }

        if( totalTime() <= 0){
            clearInterval(countdown);
            // timer is done, do something interesting..
        }

        timerPrint();
    }, 1000);
}

此外,很长一段时间计时器可能不准确。如果您想要更好的精度,请在启动计时器时读取实际当前系统时间,然后在每个时间间隔再次读取实际时间并减去两个值(当前 - 开始)以获得实际经过的时间。然后从初始总计中减去经过的时间,以获得当前剩余的时间。

相关问题