循环内的 setTimeout 行为
setTimeout behaviour inside a loop
我一直在寻找如何在循环中使用 setTimeout 函数,但关于这方面的文档似乎有限,我想在 for 循环中创建一个 setTimeout,它本身嵌入在 while 循环中。
浏览器似乎只执行一次 setTimeout 以及这个 code show it.
var value = 0
var arr = [65, 59, 80, 81, 56, 70, 72, 89, 23, 11, 4, 92, 87, 84, 50, 57, 59, 44, 49, 39, 35, 32, 0]
while(value < 10){
const span = document.createElement('span')
span.innerText = value
setTimeout(() => {
document.getElementById('spans').appendChild(span)
},1000)
value++
}
任何人都可以解释这种行为,以及如何继续让 setTimeout 在循环内的每个地方执行。
setTimeout是否以异步方式执行。
setTimeout 不像睡眠。没有停顿。它会在您指定的时间向 运行 注册一些代码。所以你在 1 秒内完成了 10 件事 运行。
因此,要使您的代码正常运行,您必须将 1 秒乘以循环索引。所以它们是偏移
var value = 0
var arr = [65, 59, 80, 81, 56, 70, 72, 89, 23, 11, 4, 92, 87, 84, 50, 57, 59, 44, 49, 39, 35, 32, 0]
while(value < 10){
const span = document.createElement('span')
span.innerText = value
setTimeout(() => {
document.getElementById('spans').appendChild(span)
},1000 * value)
value++
}
<div id="spans"></div>
现在大多数开发人员不会生成一堆超时。他们要么使用队列,要么使用 setInterval。
var value = 0
function nextValue() {
const span = document.createElement('span')
span.innerText = value
document.getElementById('spans').appendChild(span)
value++;
if (value < 10) {
window.setTimeout(nextValue, 1000);
}
}
nextValue();
<div id="spans"></div>
或区间
var value = 0;
var timer;
function update() {
const span = document.createElement('span')
span.innerText = value
document.getElementById('spans').appendChild(span)
value++;
if (value === 10) {
window.clearTimeout(timer);
}
}
timer = window.setInterval(update, 1000);
update();
<div id="spans"></div>
//<![CDATA[
/* js/external.js */
let doc, htm, bod, nav, M, I, mobile, S, Q;
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
var w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
var w = within || doc;
return w.querySelectorAll(selector);
}
// magic under here - you can put all but end load on a separate page if desired
const arr = [65, 59, 80, 81, 56, 70, 72, 89, 23, 11, 4, 92, 87, 84, 50, 57, 59, 44, 49, 39, 35, 32, 0];
const arrCount = arr.length, spans = I('spans');
let i = 0;
let interval = setInterval(()=>{
let span = M('span');
span.textContent = arr[i++]; spans.appendChild(span);
if(i === arrCount){
clearInterval(interval); interval = undefined;
}
}, 1000);
}); // end load
//]]>
/* css/external.css */
*{
box-sizing:border-box; color:#000; padding:0; margin:0;
}
html,body,.main{
width:100%; height:100%;
}
.main{
background:#333; padding:10px;
}
#spans>span{
color:#fff; font:bold 12px Tahoma, Geneva, sans-serif;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Title Here</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div class='main'>
<div id='spans'></div>
</div>
</body>
</html>
setTimeout
您需要一个“异步”循环,例如
var COUNTER = 1;
var LOOP = (DONE) => {
setTimeout (() => {
COUNTER++;
console.log ("ITERATION");
if (COUNTER === 10) {
DONE ();
return;
}
LOOP (DONE);
}, 100);
}
LOOP (() => {
console.log ("DONE");
});
我一直在寻找如何在循环中使用 setTimeout 函数,但关于这方面的文档似乎有限,我想在 for 循环中创建一个 setTimeout,它本身嵌入在 while 循环中。 浏览器似乎只执行一次 setTimeout 以及这个 code show it.
var value = 0
var arr = [65, 59, 80, 81, 56, 70, 72, 89, 23, 11, 4, 92, 87, 84, 50, 57, 59, 44, 49, 39, 35, 32, 0]
while(value < 10){
const span = document.createElement('span')
span.innerText = value
setTimeout(() => {
document.getElementById('spans').appendChild(span)
},1000)
value++
}
任何人都可以解释这种行为,以及如何继续让 setTimeout 在循环内的每个地方执行。
setTimeout是否以异步方式执行。
setTimeout 不像睡眠。没有停顿。它会在您指定的时间向 运行 注册一些代码。所以你在 1 秒内完成了 10 件事 运行。
因此,要使您的代码正常运行,您必须将 1 秒乘以循环索引。所以它们是偏移
var value = 0
var arr = [65, 59, 80, 81, 56, 70, 72, 89, 23, 11, 4, 92, 87, 84, 50, 57, 59, 44, 49, 39, 35, 32, 0]
while(value < 10){
const span = document.createElement('span')
span.innerText = value
setTimeout(() => {
document.getElementById('spans').appendChild(span)
},1000 * value)
value++
}
<div id="spans"></div>
现在大多数开发人员不会生成一堆超时。他们要么使用队列,要么使用 setInterval。
var value = 0
function nextValue() {
const span = document.createElement('span')
span.innerText = value
document.getElementById('spans').appendChild(span)
value++;
if (value < 10) {
window.setTimeout(nextValue, 1000);
}
}
nextValue();
<div id="spans"></div>
或区间
var value = 0;
var timer;
function update() {
const span = document.createElement('span')
span.innerText = value
document.getElementById('spans').appendChild(span)
value++;
if (value === 10) {
window.clearTimeout(timer);
}
}
timer = window.setInterval(update, 1000);
update();
<div id="spans"></div>
//<![CDATA[
/* js/external.js */
let doc, htm, bod, nav, M, I, mobile, S, Q;
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; nav = navigator; M = tag=>doc.createElement(tag); I = id=>doc.getElementById(id);
mobile = nav.userAgent.match(/Mobi/i) ? true : false;
S = (selector, within)=>{
var w = within || doc;
return w.querySelector(selector);
}
Q = (selector, within)=>{
var w = within || doc;
return w.querySelectorAll(selector);
}
// magic under here - you can put all but end load on a separate page if desired
const arr = [65, 59, 80, 81, 56, 70, 72, 89, 23, 11, 4, 92, 87, 84, 50, 57, 59, 44, 49, 39, 35, 32, 0];
const arrCount = arr.length, spans = I('spans');
let i = 0;
let interval = setInterval(()=>{
let span = M('span');
span.textContent = arr[i++]; spans.appendChild(span);
if(i === arrCount){
clearInterval(interval); interval = undefined;
}
}, 1000);
}); // end load
//]]>
/* css/external.css */
*{
box-sizing:border-box; color:#000; padding:0; margin:0;
}
html,body,.main{
width:100%; height:100%;
}
.main{
background:#333; padding:10px;
}
#spans>span{
color:#fff; font:bold 12px Tahoma, Geneva, sans-serif;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta charset='UTF-8' /><meta name='viewport' content='width=device-width, height=device-height, initial-scale:1, user-scalable=no' />
<title>Title Here</title>
<link type='text/css' rel='stylesheet' href='css/external.css' />
<script src='js/external.js'></script>
</head>
<body>
<div class='main'>
<div id='spans'></div>
</div>
</body>
</html>
setTimeout
您需要一个“异步”循环,例如
var COUNTER = 1;
var LOOP = (DONE) => {
setTimeout (() => {
COUNTER++;
console.log ("ITERATION");
if (COUNTER === 10) {
DONE ();
return;
}
LOOP (DONE);
}, 100);
}
LOOP (() => {
console.log ("DONE");
});