前端面试我们经常会遇到 宏任务 和 微任务 的面试题
比如:
console.log('1');
setTimeout(function() {
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
上面这个是一道经典的JS 宏任务微任务 面试题,耐心看完文章让你彻底搞懂
不说废话,一篇文章让你彻底搞懂js运行机制
- 我们都知道JS是单线程,也就是说同时只能执行一个任务,如果后面有任务,需要等到当前的任务执行完毕,才能执行后面的任务
- 但是如果后面有任务,需要等到当前的任务执行完毕,才能执行后面的任务,那如果前面的任务死循环或者非常耗时导致后面的代码不被执行,就会造成线程阻塞
- 比如 定时器 ajax 这些会非常耗时间
-
于是浏览器开辟了其他的线程来处理,所以我们叫这些程序为异步程序
-
JS中所有任务可以分成两种,一种是同步任务,另一种是异步任务
同步任务 也就是JS主线程排队执行的任务
举个例子
let a = 10
let b = 20
a = b
a = 30
//打印 a 是 30 按照顺序往下执行
同步应该还是比较好理解的
异步任务
异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,
只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行
这里的任务队列就是我们即将要说的 宏任务 和 微任务
宏任务 :setTimeout
, setInterval
, (setImmediate-node环境才可以执行
)
微任务 :Promise.then()里面执行的
, (process.nextTick node环境才可以执行
)
宏任务 微任务 的 执行顺序:
- 有同步先执行同步代码
- 同步执行完 执行微任务(
Promise.then()里面
) - 微任务按照队列一个一个执行完,开始执行宏任务,宏任务按照顺序一个一个执行
知道顺序之后我们来做一下那道面试题
/*
1. 同步
2. 微任务 promise.then process.nextTick
3. 宏任务 settimeout
*/
/*
解题思路:有同步先把同步写完,先不看promise.then()里面和setTimeout
同步写完 我们把promise.then()里面进行排序,process.nextTick只能在node中进行,他会比promise.then()执行快,这里我们了解知道一下就好
里面执行完我们开始将setTimeout进行排序
*/
/*
1和7是主线程
6和8是微任务,但是process.nextTick比promise.then()执行快
主线程和微任务执行完 开始走宏任务
宏任务里面也有微任务 我们继续开始按照队列
开始走主线程2 4 9 11
微任务 3 10 5 12
答案: 1 7 6 8 2 4 9 11 3 10 5 12
*/
console.log('1'); //第1个执行
setTimeout(function () {
console.log('2');//第5个执行
process.nextTick(function () {
console.log('3');//第9个执行
})
new Promise(function (resolve) {
console.log('4');//第6个执行
resolve();
}).then(function () {
console.log('5')//第11个执行
})
})
process.nextTick(function () {
console.log('6');//第3个执行
})
new Promise(function (resolve) {
console.log('7'); //第2个执行
resolve();
}).then(function () {
console.log('8') //第4个执行
})
setTimeout(function () {
console.log('9');//第7个执行
process.nextTick(function () {
console.log('10');//第10个执行
})
new Promise(function (resolve) {
console.log('11');//第8个执行
resolve();
}).then(function () {
console.log('12')//第12个执行
})
})
如果哪里有不懂的地方可以私信或者留言
个人抖音账号:1232924823 ;会分享一些算法视频
刚起步后续会慢慢开始更新视频