1 setTimeout(func,time)函数运行机制
setTimeout(func,time)是在time(毫秒单位)时间后执行func函数。浏览器引擎按顺序执行程序,遇到setTimeout会将func函数放到执行队列中,等到主程序执行完毕之后,才开始从执行队列(队列中可能有多个待执行的func函数)中按照time延时时间的先后顺序取出来func并执行。即使time=0,也会等主程序运行完之后,才会执行
console.log(1)
setTimeout(()=>{
console.log(2)
},0)
console.log(3);
setTimeout(()=>{
console.log(4)
},100)
console.log(5)
输出1,3,5,2,4
2 for循环和setTimeout搭配使用时出现的问题
for(var i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
},1000)
}
1s之后,同时输出 5 个 5。
因为 for 循环会先执行完(同步优先于异步优先于回调),这时五个 setTimeout 的回调全部塞入了事件队列中,然后 1 秒后一起执行了。
3 解决办法
3.1 let块级作用域
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
1s后,输出0,1,2,3,4
3.2 闭包包裹
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
1s后,输出0,1,2,3,4
3.3 传入闭包做为参数
3.3.1 传入参数
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
立刻输出0,1,2,3,4
3.3.2 不传参数
for (var i = 0; i < 5; i++) {
setTimeout((function() {
console.log(i);
})(), i * 1000);
}
立刻输出0,1,2,3,4
4 setTimeout第三个参数
for(var i=0;i<5;i++) {
setTimeout(function(i) {console.log(i)},0,i)
}
for(var i =0;i<5;i++){
setTimeout((i)=>{
console.log(i);
},0,i)
}
a = function(i) {
console.log(i)
}
for(var i =0;i<5;i++){
setTimeout(a,1000,i)
}