在游览器内部维护着一个事件队列,触发的事件会一个个的放进这个队列中,UI线程在空闲时会去查看这个队列,如果队列不为空,就取第一个事件并执行其监听函数.
首先将此段js代码放进UI线程中执行,当代码执行到setTimeout(fn, mills)时,游览器会在事件队列中放入此定时事件1,前面说过只有当UI线程空闲时才会去执行定时事件,但此时js代码还在执行,所以继续for循环,i继续自增,并且继续放入定时事件2,3,当js代码片段执行完毕后,才继续依次执行定时事件1、2、3,此时i的值已经是3了.所以在控制台中我们看到的打印结果依次是:setTimeout:1,setTimeout:2,setTimeout:3,for循环:3,for循环:3,for循环:3.
其实这样看起来非常类似与传统多线程的异步编程,代码执行流并不会等setTimeout的函数执行完毕,再继续向下执行.但我们要了解的是,其实它们仍然是串行执行的,只不过是把setTimeout中设置的函数放到队列中延后执行,从而使js代码依然先执行,执行完毕后再依次执行事件队列中的函数.