018 JS宏任务与微任务

126 阅读2分钟

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() 后执行
// 同步  异步