JS宏任务与微任务
2. 概念
**宏任务:**是指消息队列中的等待被主线程执行的事件,宏任务执行时都会重新创建栈,然后调用宏任务中的函数,栈也会随着变化,但宏任务执行结束时,栈也会随之销毁。
包括整体代码script,setTimeout,setInterval, new Promise
微任务:可以把微任务看成是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前。
Promise.then, process.nextTick(Node.js中)
微任务是基于消息队列、事件循环、UI主线程还有堆栈而来的
2. 宏任务和微任务包含什么?
**宏任务(macrotasks):**setTimeout, setInterval, setImmediate, I/O,UI rendering
**微任务(microtasks): **process.nextTick, Promise, MutationObserver
3. 关于宏任务?(代码)
// 宏任务
// script代码 setInterval, setTimeout, setImmediate
//同步、异步
// 先执行同步,再执行异步
console.log("start")
function fn() {
console.log("1234567")
}
setTimeout(() => {
console.log("setTimeout定时器!")
},2000)
fn()
console.log("end")
/* 执行结果 */
// start
// 1234567
// end
// setTimeout定时器!
4. 微任务(代码)重点
// 微任务
// 原生Promise.then()、process.nextTick、MutationObserver
function fn() {
console.log("start")
new Promise(resolve => {
console.log('111')
resolve()
console.log("222")
}).then(() => {
console.log("333")
})
console.log("end")
}
fn()
/*
start
111
222
end
333
*/
5. 宏任务和微任务的执行顺序
function fn() {
console.log(111)
setTimeout(() => {
console.log(222)
},0)
console.log(333)
new Promise(resolve => {
console.log(444)
resolve()
console.log(555)
}).then(() => {
console.log(666)
setTimeout(() => {
console.log(777)
},0)
console.log(888)
})
}
fn()
/*
111
333
444
555
666
888
222
777
*/
// 宏任务 setTimeout, setInterval
// 微任务 promise.then(), process.nextTick
// 先执行 同步 宏任务 同步 1 3 4 5 异步 2
// 后执行 异步 微任务 同步 6 8 异步 7
6. 经常遇到的面试问题
new Promise(function(resolve) {
console.log(1)
resolve()
}).then(() => {
console.log(2)
})
process.nextTick(() => {
console.log(3)
})
setImmediate(() => {
console.log(4)
})
new Promise(resolve => {
console.log(5)
resolve()
}).then(() => {
console.log(6)
})
setTimeout(() => {
console.log(7)
setImmediate(() => {
console.log(8)
})
process.nextTick(() => {
console.log(9)
})
new Promise(resolve => {
console.log(10)
resolve()
}).then(() => {
console.log(11)
})
}, 1000)
// 1 5 3 2 6 7 10 9 11 4 8
// 先执行 宏任务当中的同步任务 ---> 微任务当中的同步 --> 微任务当中的异步任务 --> 宏任务中的异步任务
// 宏任务 setTimeout setInterval setImmediate 也有先后顺序 先执行setTimeout 后执行 setImmediate I/O UI
// 微任务 promise.then() process.nextTick 有先后顺序 promise.then() 后执行
// 同步 异步