js发现个奇怪的问题

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

    setTimeout(function(){alert(i)},0)


  }

  

  这个输出的顺序是0,1,3,2,4

  不是0,1,2,3,4吗?


凤凰求蛊
浏览 462回答 1
1回答

慕妹3242003

这个问题充分的体现了javascript单线程的特性涉及的要点:setTimeout向执行队列依次添加执行函数&nbsp;let的局部作用域&nbsp;alert 阻塞首先,上述程序可以分解为以下的运行情况这里将原问题修改为以下便于理解for(let&nbsp;i=0;i<5;i++){ &nbsp;&nbsp;&nbsp;&nbsp;setTimeout(function(){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(i); &nbsp;&nbsp;&nbsp;&nbsp;},1000) }这是形成的队列function&nbsp;_fun0()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(0); }function&nbsp;_fun1()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(1); }function&nbsp;_fun2()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(2); }function&nbsp;_fun3()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(3); }function&nbsp;_fun4()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;alert(4); }假如将&nbsp;alert&nbsp;换做是&nbsp;console.log那么问题就简单多了,控制台会依次的打印:&nbsp;0,1,2,3,4。因为&nbsp;console.log不会阻塞程序的运行由于&nbsp;alert&nbsp;会阻塞程序的运行,假如等待2秒钟点击警告的确定按钮,导致延长该函数的时间线,执行&nbsp;_fun1的时候本来花费的时间可以忽略不计,程序等待1秒中就可以执行&nbsp;_fun2&nbsp;,但等待2秒之后,可以理解为超时,程序会直接跳过_fun2,而直接执行_fun3。以此类推。之后的轮询再来处理剩下未执行的代码。问题中&nbsp;setTimeout(() => {}, 0),虽然时间间隔被设置为0,但是还是会有4ms的延迟,所以可以同上述一样理解参考 《Javascript高级程序第三版》第22章 高级定时器这个问题很好,但是却被减了两票,可惜了!
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript