for循环中setTimeout使用的几个解决方案具体是什么
Admin 2022-07-19 群英技术资讯 1320 次浏览
今天这篇给大家分享的知识是“for循环中setTimeout使用的几个解决方案具体是什么”,小编觉得挺不错的,对大家学习或是工作可能会有所帮助,对此分享发大家做个参考,希望这篇“for循环中setTimeout使用的几个解决方案具体是什么”文章能帮助大家解决问题。我们先来简单了解一下setTimeout延时器的运行机制。setTimeout会先将回调函数放到等待队列中,等待区域内其他主程序执行完毕后,按时间顺序先进先出执行回调函数。本质上是作用域的问题。
因此若是这样将不会得到想要的结果输出1.2.3.4.5,而会连续输出5个6。
for (var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
这是因为setTimeout是异步执行,每一次for循环的时候,setTimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里,等待执行。只有主线上的任务执行完,才会执行任务队列里的任务。也就是说它会等到for循环全部运行完毕后,才会执行fun函数,但是当for循环结束后此时i的值已经变成了6,因此虽然定时器跑了5秒,控制台上的内容依然是6。
(注意:for循环从开始到结束的过程,需要维持几微秒或几毫秒,当定时器跑完一秒之后for循环早已经做完了。)
我们来看另一种情况:
for (var i=1; i<=5; i++) {
(function() {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
})();
}
由setTimeout的运行机制可以知道,首先会运行外部的所有主程序,虽然for循环内形成了闭包,但是fun并没有发现一个实参所以跟第一个例子并无实际差别,仍然是连续输出5个6。
使用闭包是很经典的一种做法:
for (var i=1; i<=5; i++) {
(function(j) {
setTimeout( function timer() {
console.log( j );
}, j*1000 );
})(i);
}
我们可以发现跟预期结果一致,依次输出1到5,因是因为实际参数跟定时器内部的i有强依赖。
通过闭包,将i的变量驻留在内存中,当输出j时,引用的是外部函数的变量值i,i的值是根据循环来的,执行setTimeout时已经确定了里面的的输出了。
我们还可以将setTimeout的定义和调用分别放到不同部分:
function timer(i) {
setTimeout( console.log( i ), i*1000 );
}
for (var i=1; i<=5;i++) {
timer(i);
}
控制台上输出依然是依次输出1到5。
这里再来说一说使用es6的let来解决此问题:
for (let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
这个例子与第一个相比,只是把var更改成了let,可是控制台的结果却是依次输出1到5。
因为for循环头部的let不仅将i绑定到for循环中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。setTimeout里面的function()属于一个新的域,通过var定义的变量是无法传入到这个函数执行域中的,通过使用let来声明块变量能作用于这个块,所以function就能使用i这个变量了;这个匿名函数的参数作用域和for参数的作用域不一样,是利用了这一点来完成的。这个匿名函数的作用域有点类似类的属性,是可以被内层方法使用的。
for (let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000, i );
}
由于每次传入的参数是从for循环里面取到的值,所以会依次输出1到5。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
JS实现数组去重有什么简单方法呢?JS实现数组去重的方法有很多,下面分享两个简单的方法,及注意事项。下文有实例供大家参考,对大家了解操作过程或相关知识有一定的帮助,而且实用性强,希望这篇文章能帮助大家,下面我们一起来了解看看吧。
这篇文章主要为大家详细介绍了js实现简单图片切换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
JavaScript本地存储与会话存储的实现介绍 目录 一.简单介绍 二.localStorage本地存储 三.sessionStorage会话存储 总结 一.简单介绍 本地存储和会话存储的目的,是将所输入的文件存入到浏览器中,在需要的时候,直接调用,但是本地存储和会话存储有着一定的区别,本地存储,在不主动删除的情况下,会一直保留在浏览器中,会话存储是,当前保存的内容,页面刷新还会保留在浏览器中,但是关闭页面在打开时,会发现没有数据了.这是他们两的用处和区别. 二.localStorage本地存储 如下代码 我们先给button一个监听事件,让
yield关键字只能用于生成器函数,它表示暂停函数内部代码的执行,并返回当前迭代数据。如果没有下一个yield,next返回对象的done将被放置为true。
parseInt()的作用是什么?他是js原生的方法,是用来把数字字符串转化为Number类型的数字的,还有他只是转化整数部分。
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008