宏任务与微任务

34次阅读

共计 1346 个字符,预计需要花费 4 分钟才能阅读完成。

习题

实践是检验真理的唯一标准

// 第一题
    console.log(1)
    setTimeout(()=>{console.log(3)
    })
    setTimeout(()=>{console.log(4)
    })
    var p = new Promise((res,rej)=>{console.log(5)
        res()})
    p.then(()=>{console.log(6)
    })
    console.log(2)
    // 执行顺序 1 5 2 6 3 4
// 第二题
    let fn = () => {console.log(1)
        let a = new Promise((resolve, reject) => {console.log(2)
            resolve(3)
        })
        console.log(4)
        return a
    }
    fn().then(data => console.log(data))
    // 执行顺序 1 2 4 3

setTimeout 和 setInterval、Promise 是分层执行
这里涉及一个 宏任务和微任务的概念

宏任务和微任务

微任务(Microtasks)
宏任务(task)

js 会优先执行宏任务 宏任务可以同时有多个 但会按顺序一个一个执行

每一个宏任务 后面都可以跟一个微任务队列 如果微任务队列中有指令或方法 那么就会执行 如果没有 则开始执行下一个宏任务 直到所有的宏任务执行完为止

宏任务占用性能 需要一些较早就准备好的方法 排在最后才执行的时候 又不想新增一个宏任务 那么就可以把这些方法 一个一个的放在微任务队列里面 在这个宏任务中的代码执行完后 就会执行微任务队列

// 第一题 解析
    console.log(1) // 1 宏任务
    setTimeout(()=>{ // 1 宏任务
        console.log(3) // 延后执行
    })
    setTimeout(()=>{ // 1 宏任务
        console.log(4) // 延后执行
    })
    var p = new Promise((res,rej)=>{ // 1 宏任务
        console.log(5)
        res()})
    p.then(()=>{ // 微任务
        console.log(6)
    })
    console.log(2) // 1 宏任务
    // 第一轮 先把宏任务执行完毕 
    // 第二轮 Promise 参数有了 先执行 后执行延后任务
    
    // 第二题同理 

如果还没有明白 就看这个

    console.log('第一轮 宏 1')
    Promise.resolve().then(() => {console.log('第二轮 Promise 宏》微 1')
        Promise.resolve().then(() => {console.log('第三轮 Promise 宏》微 1》(宏这里没有需要执行的东西)》微')
            Promise.resolve().then(() => {console.log('第四轮 Promise 宏》微 1》(宏这里没有需要执行的东西)》微》(宏这里没有需要执行的东西)》微')
            }) // 新加行
        }) // 新加行
    })
    setTimeout(() => {console.log('最后一轮 setTimeout 延后执行')
    });
    Promise.resolve().then(() => {console.log('第二轮 Promise 宏》微 2')
    })
    setTimeout(() => {console.log('最后一轮 setTimeout 延后执行')
    });
    console.log('第一轮 宏 2')

正文完
 0

宏任务与微任务

34次阅读

共计 950 个字符,预计需要花费 3 分钟才能阅读完成。

1 引言

首先大家来看个面试题:

console.log('sync1')
setTimeout(function() {console.log('setTimeOut1')
},0)
var promise = new Promise(function(resolve){setTimeout(function() {console.log('setTimeoutPromise')
    }, 0)
    console.log('promise')
    resolve()})
promise.then(() => {console.log('proThen')
    setTimeout(()=>{console.log('proThenSta')
    },0)
})
setTimeout(function() {console.log('lastSetTimeOut')
},0)
console.log('sync2')

哈哈哈,各位有没有很蒙圈?在此先公布正确答案:
sync1
promise
sync2
proThen
setTimeOut1
setTimeoutPromise
lastSetTimeOut
proThenSta

2 理论介绍

要理解这个题目首先要清楚事件循环机制对于宏任务和微任务的处理。宏任务和微任务表示异步任务的两种分类。在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在宏任务的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出微任务队列中的所有任务顺序执行;之后再取宏任务任务,周而复始,直至两个队列的任务都取完。常用的宏任务:整体代码 script、setTimeout、setInterval、setImmediate
常见的微任务:process.nextTick、MutationObserver、Promise.then catch finally

3 解析题目

首先第一遍同步执行,创建第一个宏任务。这时首先打印了 sync1 promise sync2
此时 then 函数有了一个微任务 然后打印了 proThen
同时创建了 分别打印 setTimeOut1 setTimeoutPromise lastSetTimeOut 的三个宏任务
以及 then 函数里 还有一个 proThenSta 的宏任务
这几个宏任务分别一次执行,于是有了上面的答案

正文完
 0