我正在练习使用递归,并且有一些我不太了解的东西。 例如,我编写了这个简单的倒计时函数,该函数应该等到第二个时间过去,直到倒数到下一秒。
我第一次写它是这样的:
function countdown(sec) {
console.warn(sec);
if(sec > 0) {
sec--;
setTimeout(countdown(sec), 1000);
}
}
每个日志之间不会等待一秒钟。 这有效:
function countdown(sec){
console.warn(sec);
setTimeout(function() {
sec--;
if (sec > 0) {
countdown(sec);
}
}, 1000);
};
我真的不明白第一种方法有什么问题。 我想这是setTimeout的东西,我不太明白,并且确定范围......?
提前感谢任何解释。
---编辑&工作,谢谢你们! ---
我不知道绑定被用作速记。
function countdown(sec) {
console.warn(sec);
if (sec > 0) {
sec--;
setTimeout(countdown.bind(null, sec), 1000);
}
}
答案 0 :(得分:1)
JosephNields对于为什么你的代码不起作用是正确的,但我还要强调递归通常不涉及改变状态值,即sec--
相反,只需将sec - 1
作为countdown
的下一个值。换句话说,设置 sec
没有增加到较小的数字,只需用较小的数字递归
var countdown = function (sec) {
console.log(sec)
if (sec > 0)
setTimeout(countdown, 1000, sec - 1)
}
countdown(10)
另外,知道计时器何时完成不是很好吗?此示例显示在您递归时传递另一个值。
var countdown = function (sec, done) {
console.log(sec)
if (sec > 0)
setTimeout(countdown, 1000, sec - 1, done)
else
done()
}
countdown(5, function () {
console.log('timer is all done!')
})
答案 1 :(得分:0)
setTimeout
的第一个参数应该是一个函数。
当您致电setTimeout(countdown(sec),1000)
时,它会被评估为setTimeout(undefined, 1000)
,因为countdown(sec)
不会返回值。
您的第二种方法有效,但作为简写,您也可以这样做:setTimout(coundown.bind(null, sec), 1000)
。这会创建一个在调用时执行countdown(sec)
的函数,它基本上等同于以下内容:
setTimeout(
function() {
countdown(sec);
},
1000
);