一、js每隔一秒打印1,2,3…
for (var i=1; i<=5; i++) {
setTimeout( ()=> {
console.log( i );
}, i*1000 ); //每隔一秒输出6
}
定时器并不是同步的,它会自动插入任务队列,等待当前文件的所有同步代码和当前任务队列里的已有事件全部运行完毕后才能执行。这时候 i 就是6 了,所以会输出⼀堆 6 。
开启了5个定时器,时间分别是1s、2s、3s、4s、5s
解决办法
1.使用闭包(立即执行函数)
console.log("11111")
for(var i = 0; i < 5; i++) {
(function(i) {
console.log("3333")
setTimeout( ()=> {
console.log( i );
}, i*1000 );
})(i)
}
console.log("2222")
//输出结果:11111 3333 333 333 333 333 2222
也是生成了5个定时器,时间分别是1s、2s、3s、4s、5s。定时器是同时执行,所以就会有了每个1s输出一个值。
- 使用let关键字
for(let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, i*1000 );
}
在for循环中使用let来定义循环变量有一个特殊效果:每一次循环都会重新声明变量i,随后的每个循环都会使用上一个循环结束时的值来初始化这个变量i。
- 使⽤ setTimeout 的第三个参数
for(var i=0;i<6;i++){
setTimeout(function(j){
console.log(j);
},i*1000,i);
}
第三个参数 就是给setTimeout第一个函数的参数
二、定时器越走越快
定时器越走越快,其实并不是定时器越走越快,而是有多个定时器在执行,定时器里面的程序执行的频率提高了。所以每次点击开启定时器之前,要先清除上一个定时器。
三、面试题alert是否会打印?
var t=true;
window.setTimeout(function(){
t=false;
},1000);
while(t){
}
alert('end');
不会打印
setTimeout是异步线程,需要等待js引擎处理完同步代码(while语句)之后才会执行。但是现在while语句直接是个死循环,js引擎没有空闲,不会执行下面的alert,也不会插入setTimeout。所以即使这个时候把setTimeout的时间改成0,他还是不会执行。