咱们知道js的最大特色就是单线程,就是同一时间只能作一件事。即使HTML5提出Web Worker容许JavaScript脚本建立多个线程,可是子线程彻底受主线程控制,且不得操做DOM。因此,这个新标准并无改变JavaScript单线程的本质。javascript
按照js回调事件的特性,将任务分为同步任务和异步任务。html
任务队列按照某种条件又能够细分为microtask 和 macrotask,一般咱们会称之为微任务和宏任务。代码执行的优先级为:主线程>微任务>宏任务。java
js中代码执行的顺序是:首先执行主线程中的代码(宏任务),开始第一次循环,执行完毕后,再执行全部的微任务,而后再执行宏任务,看该宏任务中是否有微任务,若是有的话,就将全部的微任务执行完毕。再执行新的宏任务,如此不断的反复执行下去。
事件执行机制(即js代码执行机制)以下图(图片来自ssssyoki)所示。node
//宏任务
setTimeout(function(){
console.log("我是宏任务1");
})
let p=new Promise((resolve,reject)=>{
console.log("promise1");
resolve();
});
//微任务
p.then(res=>{
console.log("我是微任务1")
});
let p2=new Promise((resolve,reject)=>{
console.log("promise2");
resolve();
});
//微任务
p2.then(res=>{
console.log("我是微任务2")
});
//宏任务
setTimeout(function(){
console.log("我是宏任务2");
})
console.log("我是主线程");
复制代码
执行结果以下所示:promise
代码解析:浏览器
宏任务 | 微任务 |
---|---|
setTimeout1 | then1 |
setTimeout2 | then2 |
//宏任务,第二次事件循环的开始
setTimeout(function() {
console.log('setTimeout1');
new Promise(function(resolve) {
console.log('setTimeout1-Promise');
resolve();
//微任务
}).then(function() {
console.log('setTimeout1-then')
})
})
new Promise(function(resolve) {
console.log('Promise');
resolve();
//微任务
}).then(function() {
console.log('then')
})
//宏任务,第三次事件循环的开始
setTimeout(function() {
console.log('setTimeout2');
new Promise(function(resolve) {
console.log('setTimeout2-promise');
resolve();
}).then(function() {
console.log('setTimeout2-then')
})
})
复制代码
上面代码在浏览器环境中的输出结果以下所示:网络
而在node环境中的输出结果是这样的,两次执行结果还不同异步
上面的代码在node环境中的执行结果以下所示。 函数
结果分析:oop
最后: node中的eventLoop运行机制比较复杂,因此还须要花费更多的时间去多多研究。
参考文档
一、这一次,完全弄懂 JavaScript 执行机制
二、JavaScript 运行机制详解:再谈Event Loop
三、Eventloop不可怕,可怕的是赶上Promise
四、浏览器说:虽然都叫event loop,可是我和node不同