js运行机制
关于javascrip运行机制的文章有很多,每个人对其的理解都大同小异,
这篇文章记录自己对javascipt运行机制的一个梳理。
javascript
是单线程语言,意味着一次只能执行一个任务,所有任务都需要排队,前一个任务执行完,才能执行后一个任务。
为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为,防止主线程的阻塞,Event Loop
的方案应用而生。
主线程运行时会产生执行栈
,栈中的代码调用某些api时,它们会在任务队列
中添加各种事件
而栈中的代码执行完毕,就会读取任务队列
中的事件,去执行那些回调
如此循环
注意,总是要等待栈中的代码执行完毕后才会去读取任务队列
中的事件
1.同步任务
异步任务
所有任务可以分为同步任务
和异步任务
同步任务
:在主线程上排队执行,前一个任务执行完,才能执行后一个任务。
异步任务
:不进入主线程,进入任务队列
,当任务队列
通知主线程,某个异步任务能执行了,该异步任务才进入主线程执行。
同步代码直接执行
异步函数到了指定时间再放到异步队列
同步执行完毕,异步队列轮询执行。
2.执行栈
任务队列
执行栈
:同步任务在主线程中执行,形成执行栈。
任务队列
:事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。
当执行栈中的任务执行完,主线程就去任务队列中找哪些任务是可以结束等待的,把结束等待的任务放入主线程中执行
3.宏任务
微任务
异步任务又分为两种,宏任务
和微任务
。
宏任务
: setTimeout,setInterval,postMessage等
微任务
: promise.then,await(await会阻塞后面的逻辑代码,等主线程执行完毕,才执行await后面的逻辑)等
当执行栈中的任务为空时,就会去任务队列中找,总是先找微任务的,再找宏任务的。
微任务队列优先于宏任务队列执行,
微任务队列上创建的宏任务会被后添加到当前宏任务队列的尾端,微任务队列中创建的微任务会被添加到微任务队列的尾端。
只要微任务队列中还有任务,宏任务队列就只会等待微任务队列执行完毕后再执行
4.流程图
文字比较抽象,流程图思路会清晰
js运行机制.png
5.总结
简言之就是JS只有一个主线程,主线程执行完执行栈的任务后去检查异步的任务队列,如果异步事件触发,则将其加到主线程的执行栈。