for(let i=0;i<5;i++){
setTimeout(function(){alert(i)},0)
}
这个输出的顺序是0,1,3,2,4
不是0,1,2,3,4吗?
for(let i=0;i<5;i++){
setTimeout(function(){alert(i)},0)
}
这个输出的顺序是0,1,3,2,4
不是0,1,2,3,4吗?
猜测原因跟alert
有关,alert
会阻塞JS
执行
以下代码不关闭alert
永远不会打印b
alert("a");
console.log("b");
所以把alert
换成console.log
试下
我理解的是应该弹出5,谷歌43测试结果也是5。
setTimeout会异步执行js。
for(var i=0;i<5;i++){
setTimeout(function(){
alert(i);
},1000)
}
代码中,每一次循环,setTimeout都会把alert事件放在事件队列,等循环完之后(主线程),i=5,再执行队列中的js,这时候i已经是5了
8 回答4.6k 阅读✓ 已解决
6 回答3.3k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.7k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
这个问题充分的体现了javascript单线程的特性
涉及的要点:
首先,上述程序可以分解为以下的运行情况
这里将原问题修改为以下便于理解
这是形成的队列
假如将
alert
换做是console.log
那么问题就简单多了,控制台会依次的打印:0,1,2,3,4
。因为console.log
不会阻塞程序的运行由于
alert
会阻塞程序的运行,假如等待2秒钟点击警告的确定按钮,导致延长该函数的时间线,执行_fun1
的时候本来花费的时间可以忽略不计,程序等待1秒中就可以执行_fun2
,但等待2秒之后,可以理解为超时,程序会直接跳过_fun2
,而直接执行_fun3
。以此类推。之后的轮询再来处理剩下未执行的代码。
问题中
setTimeout(() => {}, 0)
,虽然时间间隔被设置为0,但是还是会有4ms的延迟,所以可以同上述一样理解这个问题很好,但是却被减了两票,可惜了!