我已经阅读了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++;
}
};
运行时myFunc01();
。
没有任何暂停,i 的所有可能值都会立即列出。
这里有逻辑错误吗?
while
循环不会等待setTimeout()
完成。您需要为每个设置不同的时间延迟以不同的时间执行它们,并使用闭包来保存 i
的值。同样在您的情况下,函数将首先执行,返回值设置为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()
可以在这里使用
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>
你可以用递归更简单地做到这一点:
var i = 0;
function f1() { ... };
function f() {
f1();
i += 1;
setTimeout(function() {
if(i < 100) {
f();
}
}, 1000);
}
f();
例
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>
<小时 />可重用函数
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);
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");
}
})();
您可以创建超时函数并将其与async
/await
一起使用
// Timeout function
const timeout = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// Run some loop in async function
(async () => {
// Loop for 5 times
for(let i = 0; i <= 5; i++) {
// Do some stuff
console.log(`Some stuff ${i}`);
// Wait for timeout 1000 ms
await timeout(1000);
}
})();
是的。代码中有 2 个问题:
- setTimeout 函数接受函数作为第一个参数,但在代码中,
myfunc03(i)
不返回任何内容 - while 循环不能满足您的需求,相反,您必须使用递归函数。因为第二个函数应该在第一个超时触发后调用。
示例代码:
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>
-
我认为您在 setTimeout 上缺少一个分号,您应该尝试以以下方式传递参数:
setTimeout(myfunc03, 1000*i, i);
选择是改用setInterval()
方法。setInterval 每次都会将代码作为循环执行,直到您使用 clearInterval()
方法中断它。
示例:
var index = 0;
let incrementEveryHalfSecond = setInterval(function(){
index++;
document.querySelector("body").innerHTML += index+'</br>';
if(index == 10) clearInterval(incrementEveryHalfSecond)
}, 500)
<body></body>
观察您决定中断循环,将存储 setInterval 方法的变量作为参数传递到 clearInterval 方法中。现在,您可以创建函数来获得更好的明代码。W3学校文档
问答:[从100到1]为了简化,我颠倒了i的顺序,但你也可以用"100-i
var myfunc03 = function (i) {
document.getElementById('d01').innerHTML += i+"<br>";
};
var myFunc01 = function() {
let i=100;
let incrementEveryOneSecond = setInterval(function(){
myfunc03(i);
if(--i == 0) clearInterval(incrementEveryOneSecond);
}, 1000)
};
myFunc01();
<span id="d01"></span>
while方法运行速度很快,所有超时几乎在第一秒后执行。 你能做的是
- 而不是 while 从
myfunc03
调用$timeout
以获取下一个值 - 在您的 while 调用超时中,像
i*1000
一样增加秒
数
此外,正如其他人指出的那样,您不能使用setTimeout
这样的参数调用函数使用匿名函数,例如
...
while (i<100) {
setTimeout(
function(i){
myfunc03(i);
}, i*1000);
i++;
}
...
为此