`
yeak2001
  • 浏览: 102976 次
  • 性别: Icon_minigender_1
  • 来自: 无锡
社区版块
存档分类
最新评论

在循环中使用setTimeout

阅读更多
  首先,我想说下闭包.何为闭包,闭包是指内层的函数可以引用存在于包围它的函数内的变量,即使外层函数执行已经终止.
  其次是JS的线程问题,JS是单线程的,意味着同一时间只能执行一条语句,所以每个JS执行代码块都会阻塞异步事件的执行,这就意味着当一个异步(鼠标点击事件,AJAX,SETTIMEOUT)发生的时候,他们将排在执行队列的最后等待执行.
  最后说下setTimeout,setTimeout有2种形式:
     setTimeout(code,interval)
    setTimeout(func,interval,args)
其中code是一个字符串,这里会用到EVAL()将字符串转换成JS代码执行
func是一个函数
注意"函数"的意义,是一个表达式,而不是一个语句(执行函数)
比如你想周期性的执行一个函数
function aa() {
   //todo something
}
setTimeout("aa()",1000);
或setTimeout(a,1000);

注意第二种写法不能写成a()

在循环中使用setTimeout:
function testAnonymous() {
   var aa = 0;
   var bb = 1;
   for(var i = 0; i < 10; i++) {
      aa++;
      bb++;
      setTimeout("testDisplay(" + aa + "," + bb + ")",1000);
      //setTimeout(function(){return testDisplay(aa,bb);},1000);
    }
}
			
function testDisplay(aa,bb) {
  alert("this is aa = " + aa + " and bb = " + bb);
}

在循环中用字符串拼接的形式可以成功的执行,但是用闭包就会出现每次ALERT出来的结果都是一样的.这是为什么呢?回到刚才说的setTimeout的机制,用字符串拼接的方式每次排队等待的函数里的参数都得到了正确的初始化,而匿名函数里在进入等待队列的时候还没有执行,以至于函数体里的函数参数并没有被初始化,等到FOR循环结束,再执行匿名函数的时候aa和bb的值已经是最后一次的值了,所以不管怎么ALERT都是一样的结果.

字符串拼接的代码是比较丑陋,但是某些时候也没有其他办法可以解决,如果不在循环中,完全可以用闭包的形式来替代字符串拼接,这样能够更好的组织代码,使代码看上去更直观.
2
0
分享到:
评论
2 楼 yeak2001 2009-11-19  
不好意思啊,我最近比较忙,一直没上来看看
你的问题其实是这样的
在循环中你使用了setTimeout但是设置的间隔时间是100ms
JS是单线程的,他不会立刻执行,因为在这个setTimeout方法执行的时候FOR循环还在执行,所以他必须得在FOR循环完以后再会执行,也就是排入了等待队列,然后呢,你每次都是在100MS以后执行,这个100MS不是个累加的100MS,也就是永远都是100MS,所以等FOR循环执行完以后的100MS就会一次性执行draw 365次,修改办法是setTimeout("draw(" + i + ")", 100*i),时他们每次执行的时间有间隔就可以了

1 楼 FinrodElensar 2009-10-16  
<script>
//我想可以直观的看到用点画圆的效果,用setTimeout()方法
function draw(i)
{
    var ele=document.createElement("<div>");
    var a=300-100*Math.sin(i);//(300,100)为圆心的坐标left:300px;top:300px; 半径       //为:100
    var b=300-100*Math.cos(i);
    a=a.toString();
    b=b.toString();
    ele.style.position="absolute";
    ele.style.left=a;
    ele.style.top=b;
    ele.innerText=".";
    document.body.insertBefore(ele)'
}
</script>
<script>
for(i=0;i<360;i++)
{
   setTimeout("draw("+i+")",100);
}
//本来想隔100ms画一个点的,结果是100ms后就把整个圆画成了...,大大能解释是什么原因吗,先谢谢了.
</script>

相关推荐

    解决循环中setTimeout执行顺序的问题

    在JavaScript中,setTimeout函数可以使得函数延迟执行,然而在循环中使用setTimeout时,可能会出现执行顺序的问题。例如,在以下代码中,预期的输出结果是每隔一秒输出0,1,2,3,4,但是实际结果却是输出5。 ``` for ...

    Javascript中, setTimeout() 和 setInterval() 的方法

    在JavaScript编程中,`setTimeout()`和`setInterval()`是两个非常关键的函数,它们用于实现异步编程,特别是在处理动画、定时任务或者延迟执行代码时不可或缺。这两个函数都是全局对象`window`的方法,它们的区别...

    setTimeout应用(模拟站长之家导航)

    4. **加载提示**:如果导航栏包含异步加载的内容,`setTimeout`可以用来在加载开始后显示加载提示,并在内容加载完成后再清除提示。 5. **节流和防抖**:在处理用户输入,如连续快速点击导航链接时,可以使用`...

    JavaScript中setTimeout的那些事儿

    2. 在闭包中使用setTimeout时需要注意变量作用域问题,以及避免因循环过快而导致的问题。 3. 要注意递归的setTimeout可能会阻塞事件队列,影响页面响应。 综上所述,setTimeout是JavaScript中非常重要的一个功能,...

    JS中setTimeout()的用法详解

    在实际应用中,我们可能需要在某个条件下停止执行`setTimeout()`,这时可以使用`clearTimeout()`函数。它需要一个`setTimeout()`返回的定时器ID作为参数。 ```javascript // 创建一个定时器 var timer = setTimeout...

    js中settimeout方法加参数的使用实例.docx

    在这个例子中,所有的`setTimeout`都会在循环结束后(即`i`等于`points.length - 1`)调用`AddGuiJi`,因为它们都在引用同一个`i`。为了解决这个问题,我们可以使用闭包来保存每个迭代的`i`值: ```javascript var ...

    setTimeout使用注意事项1

    在JavaScript编程中,`setTimeout` 是一个非常常用的函数,用于在指定的时间延迟后执行一个回调函数。然而,有一些使用 `setTimeout` 的注意事项需要开发者了解,特别是在高性能和优化方面。以下是一些关键点: 1. ...

    js中的setInterval和setTimeout使用实例.docx

    javascript 中的 setInterval 和 setTimeout 使用实例 在 javascript 中,有两个重要的定时执行函数,即 setInterval 和 setTimeout。这两个函数都可以用来执行某个函数或表达式,但它们之间有一些关键的区别。 ...

    JS中的setTimeout和setInterval的区别JS中的setTimeout和setInterval的区别

    如果希望在用户完成某个动作后延迟一定时间再进行下一步处理,则可以使用`setTimeout`。 通过以上的分析可以看出,尽管`setTimeout`与`setInterval`都可以用来控制代码的执行时间,但它们的应用场景和执行方式存在...

    js中settimeout方法加参数.docx

    当在循环中使用`setTimeout`时,需要注意闭包问题。如果处理不当,可能会导致预期之外的结果。例如,在下面的例子中,虽然希望每个定时器都能输出对应的索引值,但实际上所有的定时器都会输出最后一个索引值4。 ```...

    js中setTimeout的妙用--防止循环超时

    例如,我们可以使用`Promise.all`来并行处理数组,或者使用`for...of`循环结合`await`来逐个处理数组元素,等待每个处理完成后再进行下一个。 总之,`setTimeout`在防止循环超时方面起到了关键作用。它允许我们在...

    Vue中使用 setTimeout() setInterval()函数的问题

    然而,在Vue的上下文中使用这两个函数时,需要注意一些特定的问题,主要是由于JavaScript的`this`指向规则与Vue的响应式系统之间的交互。 在给定的示例中,`setTimeout` 的回调函数内部,`this` 的上下文发生了变化...

    js中settimeout方法加参数的使用实例

    当尝试在循环中使用 `setTimeout` 时,常常会遇到一个典型的问题,即循环体内的变量 `i` 在 `setTimeout` 的回调函数执行时变成了循环结束后的值。例如,以下代码原本的目的是每隔2秒依次弹出 `points` 数组中的元素...

    模态对话框导致setTimeout失效的解决方案(一)

    在IT行业中,我们经常遇到各种各样的问题,其中之一就是在使用模态对话框时,发现`setTimeout`函数似乎不再按照预期工作。这个问题主要出现在JavaScript编程环境中,尤其是在与UI交互时。模态对话框,如Bootstrap的...

    关于JS定时器(setTimeout setInterval)定时不准问题1

    在JavaScript中,setTimeout和setInterval是两个基本的定时器函数,用于实现延迟执行或循环执行某个函数。然而,这两个函数在执行时往往和我们设置的延迟时间有出入。本文将深入探讨JS定时器的执行机制,分析why ...

    for循环 + setTimeout 结合一些示例(前端面试题)

    最近在翻看以前的老书《node.js开发指南》,恰好碰到 for 循环 + setTimeout 的经典例子,于是重新梳理了思路并记录下。 二、写在前面,setTimeout 和 setInterval 的执行机制 在日常编码中,你会发现,给 ...

    Javascript中setTimeOut和setInterval的定时器用法

    setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则是在每隔指定的毫秒数循环调用函数或表达式,直到clearInterval把它清除。也就是说setTimeout()只执行一次,setInterval()可以执行多...

    解决vue的变量在settimeout内部效果失效的问题

    这意味着在Vue实例的方法中使用箭头函数来定义`setTimeout`的回调,`this`将保持指向Vue实例。示例如下: ```javascript export default { data() { return { left: -9999, bottom: -9999 }; }, methods: { ...

    setTimeout和setInterval的区别

    因此,在处理耗时任务时,通常建议使用`setTimeout`来替代`setInterval`,并在回调函数中再次调用自身来实现周期性执行,以避免这种情况。 总之,理解`setTimeout`和`setInterval`的区别以及它们在实际开发中的应用...

Global site tag (gtag.js) - Google Analytics