为了账号安全,请及时绑定邮箱和手机立即绑定

js发现个奇怪的问题

js发现个奇怪的问题

凤凰求蛊 2018-10-19 10:11:05
for(let i=0;i<5;i++){    setTimeout(function(){alert(i)},0)  }    这个输出的顺序是0,1,3,2,4  不是0,1,2,3,4吗?
查看完整描述

1 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

这个问题充分的体现了javascript单线程的特性

涉及的要点:

setTimeout向执行队列依次添加执行函数 
let的局部作用域 
alert 阻塞

首先,上述程序可以分解为以下的运行情况

这里将原问题修改为以下便于理解

for(let i=0;i<5;i++){
    setTimeout(function(){
        alert(i);
    },1000)
}

这是形成的队列

function _fun0() {
    alert(0);
}function _fun1() {
    alert(1);
}function _fun2() {
    alert(2);
}function _fun3() {
    alert(3);
}function _fun4() {
    alert(4);
}

假如将 alert 换做是 console.log那么问题就简单多了,控制台会依次的打印: 0,1,2,3,4。因为 console.log不会阻塞程序的运行

由于 alert 会阻塞程序的运行,假如等待2秒钟点击警告的确定按钮,导致延长该函数的时间线,执行 _fun1的时候本来花费的时间可以忽略不计,程序等待1秒中就可以执行 _fun2 ,但等待2秒之后,可以理解为超时,程序会直接跳过_fun2,而直接执行_fun3。以此类推。
之后的轮询再来处理剩下未执行的代码。

问题中 setTimeout(() => {}, 0),虽然时间间隔被设置为0,但是还是会有4ms的延迟,所以可以同上述一样理解

参考 《Javascript高级程序第三版》第22章 高级定时器

这个问题很好,但是却被减了两票,可惜了!


查看完整回答
反对 回复 2018-11-28
  • 1 回答
  • 0 关注
  • 461 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信