首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >多个SetTimeouts一起执行

多个SetTimeouts一起执行
EN

Stack Overflow用户
提问于 2018-06-18 01:11:05
回答 4查看 386关注 0票数 0

我最近尝试学习网络设计,想用JavaScript做一个简单的图像淡出。我知道jQuery有一种更简单的方法,在解决这个问题一段时间后,我就用了这种方法,但我偶然发现了它,并想弄明白为什么会发生这种情况。

为了分解这个过程,假设我有一张图像,并希望它每0.1秒减少一次不透明度。因此,我使用了一个for循环,并用SetTimeout( fade ,100)调用了一个淡入淡出函数。但这10个循环中的每一个都是同时执行的。我尝试了更简单的方法:

代码语言:javascript
复制
setTimeout(fade,100);
setTimeout(fade,100); ....

即使这样,函数的所有10个实例也会一次执行。那么对于未来的项目:为什么会这样?是否有可能的变通方法?

非常感谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-06-18 01:19:39

您应该使用setInterval。

代码语言:javascript
复制
setInterval(fade,100);

setInterval用于重复性任务。它将继续运行。确保在完成后清除间隔,以防止内存泄漏。

您正在使用for循环,这不是正确的方法。

假设当前时刻的时间是:0

您运行了一个for循环并创建了5个setTimeouts。创建它需要一些时间,但您不会注意到它。

因此,每个setTimeout应该在100ms之后执行。

但它们在以下位置创建:

代码语言:javascript
复制
 1. 0.000000001
 2. 0.000000002
 3. 0.000000003
 4. 0.000000004
 5. 0.000000005

它们将在以下情况下调用回调:

代码语言:javascript
复制
 1. 100.000000001
 2. 100.000000002
 3. 100.000000003
 4. 100.000000004
 5. 100.000000005

(仅供演示)

因此,您不会注意到它们,并且这些(setTimeout和setInterval)不是绝对的。他们会花更长的时间。

希望能有所帮助。:D

票数 2
EN

Stack Overflow用户

发布于 2018-06-18 01:22:04

答案是event loop。要彻底理解此行为,您必须了解事件循环的所有阶段,尤其是如何处理setTimeoutsetInterval

关于事件循环MDN event loop的MDN文章

上升堆栈文章将帮助您清楚地了解事件循环以及微观和宏观任务

rising stack event loop explained

简而言之,所有的setTimeout都是在循环的同一tick中处理的。

对于您的情况,setInterval也要好得多

票数 0
EN

Stack Overflow用户

发布于 2018-06-18 02:08:16

有多种方法可以实现这一点。正如其他人所建议的,您可以使用setIntervalsetTimeout来递归调用。如果出于某种原因必须使用for循环,这也是可能的。

基本思想是您对第二个setTimeout的调用必须在第一次执行fade函数之后给出,否则会增加连续调用setTimeout之间的超时时间。

代码语言:javascript
复制
//\//\//\// method 1
function fadeRecur() {
  var d1 = document.querySelector( ".d1" );
  if(d1.style.opacity == '') d1.style.opacity = 1;
  //console.log(d1.style.opacity);
  if(d1.style.opacity > 0) {
    d1.style.opacity -= 0.1;
    setTimeout(fadeRecur, 100);
  }
}
setTimeout(fadeRecur, 100);

//\//\//\// method 2
var fsi;

function fadeInter() {
  var d2 = document.querySelector( ".d2" );
  if(d2.style.opacity == '') d2.style.opacity = 1;
  // console.log(d2.style.opacity);
  if(d2.style.opacity > 0) {
    d2.style.opacity -= 0.1;
  } else {
    clearInterval(fsi);
  }
}
fsi = setInterval(fadeInter, 100);


//\//\//\// method 3
function fadeLoop() {
  var d3 = document.querySelector( ".d3" );
  if(d3.style.opacity == '') d3.style.opacity = 1;
  //console.log(d3.style.opacity);
  if(d3.style.opacity > 0) {
    d3.style.opacity -= 0.1;
  }
}
for(var i=1; i<=10; i++) {
  setTimeout(fadeLoop, i*100);
}
代码语言:javascript
复制
.d1 {
  background-color: rgba(255, 0, 0, 0.5);
}
.d2 {
  background-color: rgba(0, 255, 0, 0.5);
}
.d3 {
  background-color: rgba(0, 0, 255, 0.5);
}
代码语言:javascript
复制
<div class='d1'>recursive setTimeout</div>
<div class='d2'>single setInterval</div>
<div class='d3'>setTimeout in for loop</div>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50898795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档