3-25 关于setTimeout引起的异步队列问题的研究

setTimeout()用法速查 附:深入解析

1.先自己写了一个最简单的:

console.log('global');
setTimeout(()=>{
  console.log('set');
})
console.log('global2');

输出global global2 set
是因为异步的队列与同步不同,即使延时设为0,依旧会在同步队列执行完后才会执行。

2.经典面试题

for (var i = 1;i <= 5;i ++) {

setTimeout(function timer() {

console.log(i)

},i * 1000)

}

for循环时setTimeout()不是立即执行的,它们的回调被push到了宏任务队列当中,而在执行任务队列里的回调函数时,变量i早已变成了6。那如何得到想要的结果呢?很简单,原理就是需要给循环中的setTimeout()创建一个闭包作用域,让它执行的时候找到的变量i是正确的。

解决方案

(1)引入IIFE

for(var i = 0;i<5;i ++) {

(function(i){

setTimeout(function timer() {

console.log(i)

}, i * 1000);

})(i);

}

(2)利用ES 6引入的let关键字

for(let i = 0;i<5;i++) {

setTimeout(function timer(){

console.log(i);

}, i * 1000);

}

for 循环头部的let 声明还会有一个特殊的行为。这个行为指出变量在循环过程中不止被声明一次,每次迭代都会声明。随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量。

(3)利用ES 5引入的bind函数

for (var i=1; i<=5; i++) {

setTimeout( function timer(i) {

console.log(i);

}.bind(null,i), i*1000 );

}

(4)利用setTimeout第三个参数

for (var i=1; i<=5; i++) {

setTimeout( function timer(i) {

console.log(i);

}, i*1000,i );

}

注:setTimeout函数第三个参数及以后的参数都可以作为timer函数的参数。

(5)把setTimeout用一个方法单独出来形成闭包

var loop = function (i) {

setTimeout(function timer() {

console.log(i);

}, i*1000);

};

for (var i = 1;i <= 5; i++) {

loop(i);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值