JavaScript script代码块是否属于宏任务及输出顺序疑问?

  1. JS的script代码块是属于宏任务吗?目前看到很多资料都是把script当成宏任务处理,但是见下面的代码
<script>
    console.log('script1')
    Promise.resolve().then(()=>{console.log('promise1')})
</script>

<script>
    console.log('script2')
</script>

按照script代码块是宏任务的说法,输出应该如下:

script1
promise1
script2

但是实际上的输出为:

script1
script2
promise1

这是为什么?

  1. 如果script代码块是宏任务的话,既然消息队列是由事件触发线程维护,那么在浏览器渲染HTML时,解析到script标签后,是交给事件触发线程把script代码执行任务入队,然后其入调用栈后,JS线程再进行解析?
阅读 1.7k
3 个回答

行内 script 是解析后立即执行,同步解析,同步执行。
.then 是解析后执行,异步回调。

image.png
跟ai磨了1个小时之后突然就悟了

可以理解为gui线程检测到script标签内容时,它执行不了里面的内容,因为它不是干这个的,所以它把这坨东西打包成一个整体,丢给js引擎线程去处理,然后它先休息一下。(这里不太确定是不是gui线程直接跟js引擎线程对接的,但是它们俩互斥)

就比如说你去矿区挖了一包石头,你分不清里面有哪些是翡翠哪些是玉髓,你得找专业的人做这个事情,毕竟你就是个挖矿的。

那这样的话,由于事件循环区分任务队列中任务的类型只有微任务和宏任务(其他任务),那script代码块显然不是一个微任务,那就它就只能是一个宏任务了。判断好了之后js引擎就会把内部的内容推回到主线程中的调用堆栈执行,然后等第一个script代码块执行完成(内部的同步任务和微任务执行完成,内部的宏任务还在计时执行中),休眠的gui线程又开始解析了,然后又检测到script标签,然后重复上面的逻辑。

大概是这样理解的,望指正
1728979045310.png

调用栈
|
|-- 第一个 <script> 执行
|   |-- console.log('script1') => 输出 'script1'
|   |-- Promise.then(...) => 添加微任务 'promise1'
|
|-- 第二个 <script> 执行
|   |-- console.log('script2') => 输出 'script2'
|
|-- 同步代码执行完毕,检查微任务队列
|   |-- 执行微任务 'promise1' => 输出 'promise1'
|
事件循环等待下一轮
推荐问题
宣传栏