for循环+setTimeout的延迟操作

例子:

1 for (var i = 0; i < 5; i++) {
2     setTimeout(function () {
3         console.log(i);
4     }, 100)
5 }

上述代码,输出结果显而易见是5个5,且并没有任何的延迟效果。那么为什么呢?

       首先这样的结果需要从JS的执行机制说起。JS是单线程环境,也就是说代码的执行是从上到下,依次执行。这样的执行称为同步执行。因为种种不要浪费和节约的原因。JS中引进了异步的机制。在这段代码中,哪个是同步哪个是异步呢?for循环是同步代码,而setTimeout中的是异步代码。那么JS碰到这个有同步和异步的情况下会先从上到下执行同步代码,碰到异步的代码会将其插入到任务队列当中等待。而setTimeout是延时,也就是说碰到setTimeout这个异步的代码块会根据它里面的第二个参数:延时时间来将代码插入到任务队列当中,比如上面这段代码中,第二个参数延时时间是100,也就是说执行到它的时候会在100ms之后将它插入到任务队列当中。同步代码都执行完成之后,那么JS引擎就空闲了,这个时候就轮到任务队列中的异步代码依次加载了。
      这是上面这段代码的答案的一半。另一半就来自于作用域,作用域是变量等资源的作用范围。在这段代码中准确的说是作用域链的问题,当同步代码执行完毕开始执行异步的setTimeout代码时,setTimeout中需要一个变量i,而执行的时候在当前的作用域中开始找,找不到变量i的定义,这个时候就把创建这个函数的作用域作为当前作用域,再次寻找,创建这个函数的作用域就是全局作用域,也就是找到了for循环中i,找到了之后就结束寻找变量i的行程。由于这个时候的i是全局的,而且人家已经变为了最终形态:5,setTimeout找到的就是这个i=5;所以就输出了5,下面的4次setTimeout 的执行都是类似,所以结果都是5;
所以我对这个答案的理解归结起来就是  异步加载+作用域链。

正确写法:

1 for (var i = 0; i < 5; i++) {
2     (function (i) {
3         setTimeout(function () {
4             console.log(i);
5         }, 100 * i);
6     })(i);
7 }

将延迟操作闭包,立即执行。

     

转载于:https://www.cnblogs.com/web-wy/p/10026446.html

在面试中,如果面试官会问到关于javascript中的setTimeout和for循环的问题,可以做如下回答: JavaScript中的setTimeout和for循环是两个常用的功能。setTimeout是一个用于延迟执行一段代码的方法,而for循环则用于重复执行一段代码。 setTimeout的语法是: ```javascript setTimeout(function, milliseconds) ``` 其中function是要执行的代码块,milliseconds是延迟的毫秒数。setTimeout会在指定的延迟时间后执行代码块。 常见的应用场景是在网页中实现定时效果,例如延时显示或隐藏某个元素、轮播图等。另外,通过递归调用setTimeout,可以实现循环执行某个代码块的效果。 for循环的语法是: ```javascript for (初始化变量; 判断条件; 执行操作) { //要重复执行的代码块 } ``` for循环用于重复执行指定的代码块,可以通过初始化变量、判断条件和执行操作来控制循环次数。 在面试中,可能会考察处理带有延时操作循环问题,那么就可以结合setTimeout和for循环来解决。通过将循环体包装成一个立即执行函数,并使用setTimeout来延时执行,可以实现一定的间隔时间后再执行下一次循环,避免JavaScript的单线程执行机制导致阻塞。 然而,需要注意的是,使用setTimeout延时执行循环可能会引发问题,比如可能无法准确控制循环次数、存在变量作用域问题等。所以在实际项目中,可能会使用一些更高级的方案来解决这类问题,比如利用Promise实现延时循环、使用ES6的异步函数等。 总结起来,setTimeout和for循环是JavaScript中常用的功能,对于处理延时执行循环执行的需求有很大帮助,但在具体应用中需要注意一些问题,灵活运用才能发挥出更强大的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值