一、JS事件循环机制中,首先记住一个执行顺序公式:【同】->【微】->【宏】
1 同步:一等公民(SVIP)
2 微任务:二等公民(VIP)
3 宏任务:三等公民(普通用户)
二、什么是事件循环机制
简单说,就是在执行栈中(依次压入栈里的代码先行执行)执行完毕后,再去找微任务执行,最后再找宏任务执行。
所有进入这三个栈内的被称为任务队列。
具体内容可自行搜索,网上太多
三、到底怎么进入各自的队列呢?
程序的执行顺序是自上至下,同步执行(一行一行执行),遇到异步,就跳过(异步自己去等待执行,比如ajax,settimeout,promise.then(),注意我说的不是Promse,而是我们常用到的promise.then()方法)
3.1 同步列队:
var i =0;
function(){}
console(),
promise(),promise本身是同函数一等公民,它是同步的,因为人家本来就是函数,所以内部的内容优先执行但是promise.then(),promise.catch(),promise.finally()这三个是微任务,记住就好。
其它正常的js代码
3.2 微任务列队
promise.then(),promise.catch(),promise.finally(),这三兄弟一家的,就这么写吧
await
和async
注意:微任务可没有Promise()人家是一等公民
3.3
宏任务列队
set家族:setTimeout
, setInterval
, setImmediate(NodeJs),
注意:setTimeout有个规定,时间小的优先执行,且其子内容都一起优先进入队列中
I/O
UI rendering
dom事件
ajax
===========(分装完毕)=====================================
猥琐发育,别浪
四,检测看看如何分辨,做题
4.1
console.log(1)
setTimeout(function(){
console.log(4);
})
console.log(5)
这个很简单:1 5 4
按顺序进入栈
1 同步队列
console.log(1)
console.log(5)
2 setTimeout()
4.2
console.log(1)
setTimeout(function(){
console.log(100);
},500)
setTimeout(function(){
console.log(300);
},100)
console.log(5)
答案
1,5,300,100
时间短的优先执行
4.3
console.log(1);
console.log(2);
setTimeout(function(){
console.log(3);
setTimeout(function(){
console.log(6);
})
})
setTimeout(function(){
console.log(4);
setTimeout(function(){
console.log(7);
})
})
console.log(5)
答案
1,2,5,3,4,6,7
同步:1,2,5
微:无
宏:第一层setTimeout(3,4),其次再执行内部的setTimeout,又因为没有时间,所以依然从上到下进入队列,又因为,先进的先执行,6先进,故,结果是6,7
4.4
console.log(1);
console.log(2);
setTimeout(function(){
console.log(3);
setTimeout(function(){
console.log(6);
})
},400)
setTimeout(function(){
console.log(4);
setTimeout(function(){
console.log(7);
})
},100)
console.log(5)
答案:
1,2,5
4,7 (它们时间短,他们先入栈,并先执行)
3,6(时间长,后执行)
刚才说了,setTimeout时间短的先执行,且子内容也一起进入栈,故4,7先输出,然后再执行第一个setTimeout:3,6
4.5
console.log(1)
let promise = new Promise(function(resolve,reject){
console.log(2)
resolve(3)
}).then(function(data){
console.log(data)
})
setTimeout(function(){
console.log(4);
})
console.log(5)
答案
1,2,5
3 promise.then()方法为微任务,即先执行(同->微->宏)
4 宏任务
promise(),它就是个普通函数,一等公民,所以要跟着同步入栈,即优先执行,故要输出1,2,再输出5
但promise.then()是微任务,又因为,同->微->宏,所以输出3(3是因为promise内有resolve(3)),最后输出4
最后来总结回顾一下:
-
所有同步任务都在主线程上执行,形成一个执行栈。
-
主线程之外,还存在一个任务队列。只要异步任务有了运行结果,就在任务队列之中放置一个事件。
-
一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,将队列中的事件放到执行栈中依次执行。
-
主线程从任务队列中读取事件,这个过程是循环不断的。
记住:【同】->【微】->【宏】