一 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
二 for循环和setTimeout搭配使用时出现的问题
for(var i=0;i<5;i++){
setTimeout(()=>{
console.log(i)
},1000)
}
1s之后,同时输出 5 个 5。
因为 for 循环会先执行完(同步优先于异步优先于回调),这时五个 setTimeout 的回调全部塞入了事件队列中,然后 1 秒后一起执行了。
三 解决方法
1 let块级作用域
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
1s后,输出0,1,2,3,4
2 闭包
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
1s后,输出0,1,2,3,4
失败方法 (变量不传)
for (var i = 0; i < 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, 1000);
})();
}
1秒后,输出5,5,5,5,5
失败方法 (变量不传)
for (var i = 0; i < 5; i++) {
(function() {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
1秒后,输出5,5,5,5,5
3 传入闭包作为函数
(1)参入参数
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}
立刻输出0,1,2,3,4
(2)不传参数
for (var i = 0; i < 5; i++) {
setTimeout((function() {
console.log(i);
})(), i * 1000);
}
立刻输出0,1,2,3,4
4 函数封装
1 匿名函数封装
a = function(i) {
console.log(i);
}
for (let i=0; i< 5; i++) {
setTimeout(() => {
a(i)
}, 1000);
}
1秒后,输出0,1,2,3,4
2 setTimeOut函数接收第三个参数
for(var i =0;i<5;i++){
setTimeout((i)=>{
console.log(i);
},1000,i)
}
a = function(i) {
console.log(i)
}
for(var i =0;i<5;i++){
setTimeout(a,1000,i)
}
1秒后,输出0,1,2,3,4