JS 引擎的执行机制:事件轮询event loop
举例
setTimeout(function() { console.log(1) }, 0); new Promise(function executor(resolve) { console.log(2); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(3); }).then(function() { console.log(4); }); console.log(5);
结果:2 3 5 4 1
解释:
按照这种分类方式:JS的执行机制是:
-
首先判断JS是同步还是异步,同步就进入主进程,异步就进入event table
-
异步任务在event table中注册函数,当满足触发条件后,被推入event queue
-
同步任务进入主线程后一直执行,直到主线程空闲时,才会去event queue中查看是否有可执行的异步任务,如果有就推入主进程中
以上三步循环执行,这就是event loop。
准确的划分方式是:
-
macro-task(宏任务):包括整体代码script,setTimeout,setInterval
-
micro-task(微任务):Promise,process.nextTick
按照这种分类方式,JS的执行机制是:
-
执行一个宏任务,过程中如果遇到微任务,就将其放到微任务的“事件队列”里
-
当前宏任务执行完成后,会查看微任务的“事件队列”,并将里面全部的微任务依次执行完
-
重复以上2步骤,结合event loop(1) event loop(2),就是更为准确的JS执行机制了
尝试按照刚学的执行机制,去分析例2:
-
首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的“队列”里
-
遇到 new Promise直接执行,打印"马上执行for循环啦"
-
遇到then方法,是微任务,将其放到微任务的“队列”里。
-
打印 "代码执行结束"
-
本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数,打印"执行then函数啦"
-
到此,本轮的event loop 全部完成。
-
下一轮的循环里,先执行一个宏任务,发现宏任务的“队列”里有一个setTimeout里的函数,执行打印"定时器开始啦"
参考链接:
https://mp.weixin.qq.com/s/WNTndyAGAh0k2M15LR3iKA