Javascript 函数 setTimeout 和 setInterval 不工作
Javascript function setTimeout and setIntervall not working
我遇到了这个问题,这个功能不起作用,我不知道为什么..
这个函数应该数到 10(10 秒内)。为此,我使用带有 setTimeout 函数的 for 循环 - 持续时间设置为 1000 毫秒。
对于我使用的 setInterval 函数,它应该继续下去。
function timer() {
var time=10;
for(i=0; i<time; i++){
setTimeout(console.log(i+1), 1000);
}
}
setInterval(timer, 10000);
问题是,它不起作用,我不明白为什么……我找到了另一个可行的解决方案,但想知道这个问题。 :)
当我在 Firebug 调试器中 运行 你的代码时,我看到:
TypeError: can't convert console.log(...) to string
我在您的代码中添加了关于该错误的评论:
function timer() {
var time=10;
for(i=0; i<time; i++){
// The source of error is the line below
// Type error: setTimeout needs a function as first argument!
setTimeout(console.log(i+1), 1000);
}
}
setInterval(timer, 10000);
更正后的版本可能是
function timer() {
var time=10;
for(i=0; i<time; i++){
setTimeout(function() { console.log(i+1); }, 1000);
}
}
setInterval(timer, 10000);
但是,上述更改修复了类型错误,但未修复逻辑。
您可能想这样做:
var counter = 0;
var count = function() {
console.log(++counter);
if (counter >= 10) {
clearInterval(timer);
}
};
var timer = setInterval(count, 1000);
一旦回调函数 count
注意到计数器传递了值 10,它将停止周期性定时器,其 ID 在设置时保存在变量 timer
中。
似乎什么都没发生的原因是您使用的方式 setTimeout
。您没有提供事件处理程序,而是调用 console.log
并尝试使用该调用中的 return 值作为事件处理程序。
最接近的至少会做某事的事情是制作一个调用 console.log
:
的函数
setTimeout(function(){ console.log(i+1) }, 1000);
但是,您会注意到它会一次记录值 11
十次,每十秒一次,无限期。
尽管循环从 0 计数到 9,但您在每次迭代中启动超时,该超时将在创建时触发一秒。由于所有十个超时是同时创建的,因此它们将被同时触发。每个处理程序没有单独的变量 i
,因此它们都会在触发时显示变量中的值,并且在循环完成之前可以调用它们中的任何一个,它们将全部显示显示最终值 10 + 1.
您同时使用了间隔和超时,您应该使用其中之一。
你可以在一个循环中开始超时,但是你应该只做一次,而不是在一个间隔中,你应该指定从开始到你想要触发它的时间:
var time = 10;
for (var i = 1; i <= time; i++){
setTimeout(function() { console.log('tick'); }, 1000 * i);
}
如果要在事件处理程序中使用变量,则需要为每次迭代创建变量的副本:
var time = 10;
for (var i = 1; i <= time; i++){
(function(copy){
setTimeout(function() { console.log(copy); }, 1000 * i);
})(i);
}
你可以使用间隔,但是你没有循环,间隔就是循环。使用 clearInterval
在循环结束时停止它:
var i = 1, time = 10, handle;
function timer() {
console.log(i);
i++;
if (i > time) clearInterval(handle);
}
handle = setInterval(timer, 1000);
首先,它不起作用,因为 setTimeout 调用错误。即使您的 setTimeout 调用有效,这里还有另一个问题。您的代码实际上每 10 秒打印 11。
function timer() {
var time = 10;
for (i = 0; i < time; i++) {
setTimeout(function() {
console.log(i + 1)
}, 1000);
}
}
setInterval(timer, 10000);
因为,您每秒都会执行连续的 setTimeout 调用,并且您正在对变量形成闭包 i
。
您需要注意闭包,并且必须在打印完第二个后调用。
function timer() {
var p = Promise.resolve();
for (var i = 0; i < 10; i++) {
p = p.then(closure(i));
}
}
function closure(i) {
return (function () {
return new Promise(function (resolve) {
setTimeout(function () {
document.getElementById('results').innerHTML = (i + 1) + '\n';
resolve();
}, 1000);
})
});
}
timer();
setInterval(timer, 10000);
<pre id="results"></pre>
我遇到了这个问题,这个功能不起作用,我不知道为什么.. 这个函数应该数到 10(10 秒内)。为此,我使用带有 setTimeout 函数的 for 循环 - 持续时间设置为 1000 毫秒。
对于我使用的 setInterval 函数,它应该继续下去。
function timer() {
var time=10;
for(i=0; i<time; i++){
setTimeout(console.log(i+1), 1000);
}
}
setInterval(timer, 10000);
问题是,它不起作用,我不明白为什么……我找到了另一个可行的解决方案,但想知道这个问题。 :)
当我在 Firebug 调试器中 运行 你的代码时,我看到:
TypeError: can't convert console.log(...) to string
我在您的代码中添加了关于该错误的评论:
function timer() {
var time=10;
for(i=0; i<time; i++){
// The source of error is the line below
// Type error: setTimeout needs a function as first argument!
setTimeout(console.log(i+1), 1000);
}
}
setInterval(timer, 10000);
更正后的版本可能是
function timer() {
var time=10;
for(i=0; i<time; i++){
setTimeout(function() { console.log(i+1); }, 1000);
}
}
setInterval(timer, 10000);
但是,上述更改修复了类型错误,但未修复逻辑。
您可能想这样做:
var counter = 0;
var count = function() {
console.log(++counter);
if (counter >= 10) {
clearInterval(timer);
}
};
var timer = setInterval(count, 1000);
一旦回调函数 count
注意到计数器传递了值 10,它将停止周期性定时器,其 ID 在设置时保存在变量 timer
中。
似乎什么都没发生的原因是您使用的方式 setTimeout
。您没有提供事件处理程序,而是调用 console.log
并尝试使用该调用中的 return 值作为事件处理程序。
最接近的至少会做某事的事情是制作一个调用 console.log
:
setTimeout(function(){ console.log(i+1) }, 1000);
但是,您会注意到它会一次记录值 11
十次,每十秒一次,无限期。
尽管循环从 0 计数到 9,但您在每次迭代中启动超时,该超时将在创建时触发一秒。由于所有十个超时是同时创建的,因此它们将被同时触发。每个处理程序没有单独的变量 i
,因此它们都会在触发时显示变量中的值,并且在循环完成之前可以调用它们中的任何一个,它们将全部显示显示最终值 10 + 1.
您同时使用了间隔和超时,您应该使用其中之一。
你可以在一个循环中开始超时,但是你应该只做一次,而不是在一个间隔中,你应该指定从开始到你想要触发它的时间:
var time = 10;
for (var i = 1; i <= time; i++){
setTimeout(function() { console.log('tick'); }, 1000 * i);
}
如果要在事件处理程序中使用变量,则需要为每次迭代创建变量的副本:
var time = 10;
for (var i = 1; i <= time; i++){
(function(copy){
setTimeout(function() { console.log(copy); }, 1000 * i);
})(i);
}
你可以使用间隔,但是你没有循环,间隔就是循环。使用 clearInterval
在循环结束时停止它:
var i = 1, time = 10, handle;
function timer() {
console.log(i);
i++;
if (i > time) clearInterval(handle);
}
handle = setInterval(timer, 1000);
首先,它不起作用,因为 setTimeout 调用错误。即使您的 setTimeout 调用有效,这里还有另一个问题。您的代码实际上每 10 秒打印 11。
function timer() {
var time = 10;
for (i = 0; i < time; i++) {
setTimeout(function() {
console.log(i + 1)
}, 1000);
}
}
setInterval(timer, 10000);
因为,您每秒都会执行连续的 setTimeout 调用,并且您正在对变量形成闭包 i
。
您需要注意闭包,并且必须在打印完第二个后调用。
function timer() {
var p = Promise.resolve();
for (var i = 0; i < 10; i++) {
p = p.then(closure(i));
}
}
function closure(i) {
return (function () {
return new Promise(function (resolve) {
setTimeout(function () {
document.getElementById('results').innerHTML = (i + 1) + '\n';
resolve();
}, 1000);
})
});
}
timer();
setInterval(timer, 10000);
<pre id="results"></pre>