JS运行机制详解(Event Loop)
今天学习了一下关于JS的运行机制,在这里分享一下,顺便也加深一下自己的印象。
1.基础知识
- js作为浏览器脚本语言,它的主要用途是与用户互动,以及操作DOM,因此js是单线程,也避免了同时操作同一个DOM的矛盾问题;
- 为了利用多核CPU的计算能力,H5的Web Worker实现的“多线程”实际上指的是“多子线程”,完全受控于主线程,且不允许操作DOM;
- js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)
- 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack);
- 如果在微任务执行期间微任务队列加入了新的微任务,会将新的微任务加入队列尾部,之后也会被执行。
2.JS中的异步操作
- setTimeOut
- setInterval
- ajax
- promise
- I/O
3.同步任务与异步任务
- 同步任务(synchronous):在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
- 异步任务(asynchronous):不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
4.宏任务与微任务
这里需要注意new Promise会进入到主线程中立即执行,而promise.then则属于微任务。
- 宏任务(macro-task):整体代码script、setTimeOut、setInterval
- 微任务(mincro-task):promise.then、promise.nextTick(node)
5.Event Loop事件循环
(1). 整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为两部分:“同步任务”、“异步任务”;
(2). 同步任务会直接进入主线程依次执行;
(3). 异步任务会再分为宏任务和微任务;
(4). 宏任务进入到Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中;
(5). 微任务也会进入到另一个Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中;
(6). 当主线程内的任务执行完毕,主线程为空时,会检查微任务的Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务;
(7). 上述过程会不断重复,这就是Event Loop事件循环。
6.废话
以上就是关于JS运行机制的理论解释了。第一次写博客,最近还会分享一些散碎的知识,等过一阵俺的书到了就可以开始系统的记录一下自己的学习过程了,这种感觉还是和学习笔记不同,有种更生动的感觉。
参考文献
- StarryLake《js运行机制详解(Event Loop)》
- 链接:https://www.jianshu.com/p/e06e86ef2595