您的位置:首页 > Web前端 > JavaScript

初步理解js事件循环机制

2018-09-12 14:54 405 查看

看了几个篇关于JavaScript事件循环机制(event loop)的相关文章,做一个自我总结,也希望大佬能帮我指正

首先,JavaScript是单线程,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。所以,JavaScript语言的设计者将任务分为两大类,同步任务和异步任务。

再者,JavaScript有一个main thread主线程,一个调用堆栈call-stack(这是一个函数的执行栈),多个任务队列task-queue(这是异步回调函数的队列,同时不同任务源的异步任务会放到不同的队列中,并循环调用队列,直到所有的任务都执行完)。

任务队列分成两类:
macro-task(宏任务)包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。 
micro-task(微任务)包括:process.nextTick, Promise, Object.observe, MutationObserver 

setTimeout,Promise这样的,我们称为任务源。其中setTimeout与setInterval是同源的。

事件循环过程macro-task->micro-task->macro-task->micro-task

第一步:
在主线程中,js引擎去读取script整体代码。碰到函数,则会将函数推入call-stack中去执行。直到将整体代码解读完成。(这一步即是处理macro-task队列中的script队列)

第二步:
第二步就是对call-stack中的函数的相关处理方式。
在stack中,函数代码会调用相关的外部API(WebAPIs)。例如,调用栈中遇到DOM操作、ajax请求以及setTimeout等WebAPIs的时候就会交给浏览器内核的其他模块进行处理,webkit内核在Javasctipt执行引擎之外,有一个重要的模块是webcore模块。对应3种API,webcore分别提供了DOM Binding、network、timer模块来处理底层实现。等到这些模块处理完这些操作的时候将能执行回调函数放入任务队列中。

第三步:
循环调用队列函数(micro-task->macro-task->micro-task
首先执行全部可执行的micro-task,再执行一个macro-task队列,再执行全部可执行的micro-task。
同时,在队列中的函数也是会进入call-stack中进行第二步的处理。

队列中的优先级,有一个大概的顺序process.nextTick > promise.then > setTimeout > setImmediate;优先级执行顺序可能还会和具体的宿主环境有关;边城大神也说的对对于异步我们更不应该去依赖他们的执行顺序既然是异步就当作无序的来处理。

前端基础进阶(十二):深入核心,详解事件循环机制

问题:

1.如果一个任务源队列的回调函数不停增加,是否会导致该队列一直在被处理,无法切换到其他的任务源

2.调用WebAPIs的异步函数,是在主线程中执行函数的主体代码,还是在WebAPIs对应的模块中执行主体代码

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: