我正在阅读StackOverflow here上的答案,该答案解释了如何使用setTimeout在网页上创建一种重复循环。但是,我想知道为什么setTimeout需要匿名函数才能工作。请考虑以下代码:
trainingTimer(60,0);
function trainingTimer(duration,c) {
document.getElementById("timer").innerHTML = "Time left: "+(duration-c);
if(duration==c) {
alert("Time is up!");
}
else {
window.setTimeout(trainingTimer(duration,c+1),1000);
}
}
我根据上面链接的答案编写了这个,但是当它运行时,它会立即遍历所有60个trainingTimer
个调用,并立即在我的网页上显示“剩余时间:0”。但是,如果我修改
window.setTimeout(trainingTimer(duration,c+1),1000);
并将trainingTimer(duration,c+1)
包装在像这样的匿名函数中
window.setTimeout(function() {trainingTimer(duration,c+1)},1000);
然后代码完全正常。
我想知道为什么我必须在匿名函数中包装一个命名函数,以便setInterval正常工作。感谢您的帮助。
答案 0 :(得分:4)
这个
window.setTimeout(trainingTimer(duration,c+1),1000);
与
相同var result = trainingTimer(duration,c+1);
window.setTimeout(result,1000);
它获取执行方法的结果并分配它。
因为训练计时器方法什么都不返回。你的代码基本上是这个
trainingTimer(duration,c+1);
window.setTimeout(undefined, 1000);
答案 1 :(得分:2)
运行时必须在调用函数之前评估传递给任何函数的参数列表。您在此代码中首先传递给setTimeout
:
window.setTimeout( trainingTimer(duration,c+1), 1000 );
是调用函数的结果,而不是函数本身。在函数中包装它可以解决这个问题。
该功能不必是匿名的:
function callTrainingTimer() {
trainingTimer( duration, c + 1);
}
// ...
window.setTimeout(callTrainingTimer, 1000);
也有效。
答案 2 :(得分:2)
因为setTimeout
的工作原理。它的第一个参数是你希望它在x毫秒后运行的函数。
当你这样做时:
window.setTimeout(trainingTimer(duration,c+1),1000);
您正在做的是立即正在运行 trainingTimer
,并将其返回值发送到setTimeout
。
你需要给它一个功能,这就是你做的原因:
window.setTimeout(function() {
trainingTimer(duration, c+1);
},1000);
是一种没有功能的方法,但它 NOT 推荐。
window.setTimeout('trainingTimer(duration,c+1)', 1000);
这将使用eval()
来运行代码。这不是传递函数,而是不推荐。 eval()
不安全,请勿使用。