Javascript while 循环中的 setTimeout() 方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37728184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
setTimeout() method inside a while loop
提问by havz
I have read the relevant pages on w3schools and other similar questions here but cannot seem to understand what's wrong about the following bit :
我已经阅读了有关 w3schools 和其他类似问题的相关页面,但似乎无法理解以下内容有什么问题:
var myfunc03 = function (i) {
document.getElementById('d01').innerHTML += 100-i+"<br>";
};
var myFunc01 = function() {
i=0;
while (i<100) {
setTimeout(myfunc03(i), 1000)
i++;
}
};
when myFunc01();
is run.
什么时候myFunc01();
运行。
There's no pause whatsoever and all possible values for i is listed at once.
没有任何停顿, i 的所有可能值都会立即列出。
Is there a logical mistake here?
这里有逻辑错误吗?
回答by Pranav C Balan
The while
loop will not wait for setTimeout()
to complete. You need to set different time delay for each to execute them with different times and use closure for holding the value of i
. Also in your case, function will be executed initially and return value is setting as argument in setTimeout()
, so either you need to call the function inside an anonymous function or set the function directly.
该while
循环不会等待setTimeout()
来完成。您需要为每个设置不同的时间延迟以不同的时间执行它们并使用闭包来保存 的值i
。同样在您的情况下,函数将最初执行并且返回值设置为参数 in setTimeout()
,因此您需要在匿名函数中调用该函数或直接设置该函数。
var myFunc01 = function() {
var i = 0;
while (i < 100) {
(function(i) {
setTimeout(function() {
document.getElementById('d01').innerHTML += 100 - i + "<br>";
}, 1000 * i)
})(i++)
}
};
myFunc01();
<span id="d01"></span>
虽然
setInterval()
setInterval()
可以在这里使用var myFunc01 = function() {
var i = 0;
// store the interval id to clear in future
var intr = setInterval(function() {
document.getElementById('d01').innerHTML += 100 - i + "<br>";
// clear the interval if `i` reached 100
if (++i == 100) clearInterval(intr);
}, 1000)
}
myFunc01();
<span id="d01"></span>
回答by Sun
You can do it more simplywith recursion:
您可以使用递归更简单地做到这一点:
var i = 0;
function f1() { ... };
function f() {
f1();
i += 1;
setTimeout(function() {
if(i < 100) {
f();
}
}, 1000);
}
f();
Example
例子
var i = 0;
var myfunc03 = function(i) {
document.getElementById('d01').innerHTML += 100 - i + "<br>";
};
var myFunc01 = function() {
myfunc03(i);
i += 1;
setTimeout(function() {
if (i < 100) {
myFunc01();
}
}, 1000);
}
myFunc01();
<div id="d01"></div>
A reusable function
可重用的函数
function say(sentence) {
console.log(sentence);
}
function sayHello() {
say("Hello!");
}
var fn = sayHello;
var count = 10;
var ms = 1000;
function repeat(fn, count, ms) {
var i = 0;
function f() {
fn();
i += 1;
setTimeout(function() {
if (i < count) {
f();
}
}, ms);
}
f();
}
repeat(fn, count, ms);
回答by hoozecn
Yes. There are 2 problems in your code:
是的。您的代码中有两个问题:
- The setTimeoutfunction accept a function as the first argument, but in your code,
myfunc03(i)
returns nothing - The while loop won't meet you needs, instead, you have to use recursive function. Since the second function should be invoked after the first timeout is fired.
- 该setTimeout的函数接受一个函数作为第一个参数,但在你的代码,
myfunc03(i)
没有返回 - while 循环不能满足您的需求,相反,您必须使用递归函数。由于第二个函数应该在第一个超时触发后调用。
Sample code:
示例代码:
var myfunc03 = function (i) {
setTimeout(function() {
document.getElementById('d01').innerHTML += 100-i+"<br>";
if (i < 100) {
i++;
myfunc03(i);
}
}, 1000);
};
var myFunc01 = function() {
myfunc03(0);
};
myFunc01();
<div id="d01"></div>
回答by shoesel
while
waiting for setTimeout
:
while
等待setTimeout
:
(async () => {
var i = 0;
while (await new Promise(resolve => setTimeout(() => resolve(i++), 1000)) < 100) {
console.log("I get printed 100 times every second");
}
})();
回答by Utkarsh Sinha
I think you are missing a semicolon on the setTimeout and you should try passing the arguments in the below fashion:
setTimeout(myfunc03, 1000*i, i);
我认为您在 setTimeout 上缺少分号,您应该尝试以以下方式传递参数:
setTimeout(myfunc03, 1000*i, i);
回答by Viral Shah
the while method runs quickly and all timeout almost gets executed after first second.. what you can do is
while 方法运行很快,并且所有超时几乎在第一秒后执行.. 你可以做的是
- Instead of while call
$timeout
frommyfunc03
for next value - inside your while call timeout with increasing seconds like
i*1000
- 而不是 while 调用
$timeout
来自myfunc03
下一个值 - 在您的 while 呼叫超时中,随着秒数的增加,例如
i*1000
Also, as others pointed out you can't call functions with params like that from setTimeout
use anonymous function like
此外,正如其他人指出的那样,您不能setTimeout
使用匿名函数调用具有类似参数的函数
...
while (i<100) {
setTimeout(
function(i){
myfunc03(i);
}, i*1000);
i++;
}
...
for that
为了那个原因