time 0
image.png
什么叫执行栈?
程序放里面一个一个的执行,在这里面执行的任务有同步代码,宏任务的异步代码
宏任务队列中的代码放入执行栈是有条件的,事件环走一圈放进去一个,比如ajax放入执行栈的条件是什么,ajax请求的响应回来了,被ajax收到了,setTimeout时间到了,用户交互事件方式时,一个环,一次环运行,只能放一个任务进来

time 2m09s
宏任务队列中先进先出,第一个放进宏任务得到事件,会第一个放进js执行栈中运行。不会反之,如果有多个setTimeout一个100ms、一个200ms,100ms的应该先运行,它先放入宏任务队列,所以得先进先出

time 2m54s
执行栈中的代码执行完毕后,看微任务里面有没有东西,先看promise then里面的,微任务里面的所有任务需要一次清空,它不像宏任务一样一次只执行一个,清空一个,微任务是每一次执行完毕都会去清空所有的微任务

微任务清空完毕了会走gui渲染线程
之后,宏任务队列取出最上面的一个宏任务的回调,放进执行栈,之后又看微任务,因为可能setTimeout里的回调里面有微任务,所以是通过走微任务,判断微任务队列里面有没有任务,是否为空来判断有没有微任务,所以走微任务队列有两个作用,1判断有没有微任务,相当与if()2有,执行队列里面的微任务,知道都执行完毕,清空所有微任务

题目

题目1

time 7m03s
index.js

  1. document.body.style.backgroundColor = 'orange';
  2. console.log(1);
  3. setTimeout( ()=> {
  4. document.body.style.backgroundColor = 'green';
  5. console.log(2);
  6. },0)
  7. Promise.resolve(3).then(num=>{
  8. document.body.style.backgroundColor = 'purple';
  9. console.log(num);
  10. });
  11. console.log(4);

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <script src="./index.js"></script>
  9. </body>
  10. </html>

事件触发线程event loop
事件环的运行流程与基本案例的分析 - 图2

第一步
运行html,引入代码,运行代码,js引擎线程
先把script(index.js中所有代码)放入js引擎线程执行栈中
js引擎线程开始处理代码,这时候都没有发生预编译,因为之前js引擎线程刚刚得知要运行这个代码,刚刚得到(要运行的)代码,没有执行代码

  1. <script src="./index.js"></script>

image.png

开始执行
现在开始执行代码了,之后依次运行index.js中的代码
document.body.style.backgroundColor = ‘orange’;是同步代码直接运行,改变背景颜色变成了orange,改变body的内联style属性
,代码运行生效了,html改变了,但视觉效果不会变,因为js引擎线程运行时,gui渲染线程不会运行,没有走渲染,视觉效果没有改变

image.png

time 9m43s
setTimeout运行,宏任务队列里面拿到的不是setTimeout函数,而是setTimeout里传入的回调函数cb
在这里面等100ms,cb进入宏任务队列
image.png

time 11m34s
image.png

Promise.resolve(3)与console一样是同步任务,.then中的是异步任务
Promise是一个微任务,异步任务,但前提是处理回调函数的时候,内部回调函数的时候,比如resolve、reject,then中的函数
promise是个微任务,但是不一定进队列,进队列一定是then运行的时候,这里Promise.resolve(3)执行之后,then才能执行
then执行,then是同步任务,但then里面的cb是微任务

time 13m50s
console.log(4)运行,放入调用栈,打印4
image.png

time 15m01s
这时候同步代码执行完毕了,调用栈中没有任何任务,开始执行微任务队列里的任务,全部把微任务队列里面的任务执行完毕,清空
image.png

time 15m06s
微任务队列中的任务全部执行完成了,清空微任务
image.png

微任务空了,gui渲染线程开始运行、执行,渲染html界面,颜色改变
image.png
time 15m15s
宏任务队列中的任务开始执行,setTimeout 中回调函数cb运行,先放入执行栈
image.png

setTimeout中的回调函数在调用栈执行,改变了内联元素style中的内容,gui就需要执行了
image.png

微任务队列为0->gui渲染线程执行,颜色改变了

image.png

image.png

总结

整个script是宏任务,宏任务里面可以有同步任务,微任务,宏任务都可以有
1执行栈里面全部代码执行、所有任务执行
2微任务队列里面所有任务执行
3gui渲染
4宏任务队列最上面任务放入执行栈
5执行栈执行里面全部代码,其实和一是一样的
周而复始,直到执行栈、微任务队列(栈)、宏任务队列里面所有任务全部都执行完毕了,才会停止
一旦ajax收到请求,或用户点击事件,又有宏任务进入宏任务队列,就继续把宏任务队列中的代码推入执行中执行,继续上述步骤