说下我的理解吧,先明确几个基本概念 js引擎只负责实现ecmascript标准,按照标准执行代码,它不关心也不知道event loop的存在,你给它什么代码它就执行什么 event loop是 js运行环境内部使用的机制,运行环境也就是Node以及各种各样的浏览器 js引擎执行代码时会有一个执行栈,执行栈中的代码执行完毕后,浏览器(JS运行环境)才会从event queue中取出事件,如果该事件有对应的callback,则再次交给js引擎执行。 所有的事件在产生后都会被浏览器放到event queue中,事件可以来源于鼠标键盘、网络IO、定时器等。event queue一般是由多个不同优先级的队列组成,分别对应不同类型的事件,具体的细节由实现者自己决定。 现在,根据你描述的问题,我尝试还原一下整个过程。 浏览器取得HTML文件后,做的第一件事就是解析HTML(它内部有另外的模块来做这件事),构建DOMTree,当遇到script标签,会停止解析,交给js引擎执行标签内的javascript代码块,这就是我们通常说的js会阻塞页面渲染。 此时js引擎执行栈中只有第一个script标签内的代码。一旦这段代码执行完毕,浏览器会检查event queue,这个时候,根据event queue的情况以及浏览器自身的实现策略就可能会有不同的结果。 浏览器可能会按照先后顺序,或者它预定的优先级依次取出全部事件给js引擎执行callback,还有可能为了加快页面渲染速度,只取出部分高优先级事件。 最后浏览器继续解析页面,遇到下一个script标签再次交给js引擎执行代码 我在Chrome57下多次执行了你的代码,只会出现第1,3种情况 这很好理解,当第一段script执行完时,chrome取出事件时,忽略低优先级的timeout事件,如果已经有xhr事件则取出,没有就继续解析HTML,碰到第二个script再次用js引擎执行。 最后,已上纯属个人见解。有些概念其实依赖于具体的实现的,不同浏览器的差异可能会导致表现出来的行为就不一样,要深入的了解细节只能去看它们的源码了。。。