×

如何理解微任务,宏任务与事件循环(Event Loop)?

提问者:Terry2023.07.21浏览:1613

所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

运行机制:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

这种运行机制又称为Event Loop(事件循环)。

宏任务和微任务都是异步任务,主要区别在于他们的执行顺序。

宏任务:

包括整体代码script,setTimeout,setInterval、setImmediate。

微任务:

原生Promise(有些实现的promise将then方法放到了宏任务中)、process.nextTick、 MutationObserver

js异步有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入event queue,然后再执行微任务,将微任务放入event queue最骚的是,这两个queue不是一个queue。当你往外拿的时候先从微任务里拿这个回调函数,然后再从宏任务的queue上拿宏任务的回掉函数。

例子1:

setTimeout(()=>{
console.log('setTimeout1')
},0)
let p = new Promise((resolve,reject)=>{
console.log('Promise1')
resolve()
})
p.then(()=>{
console.log('Promise2')
})

例子2:

Promise.resolve().then(()=>{
console.log('Promise1')
setTimeout(()=>{
console.log('setTimeout2')
},0)
})
setTimeout(()=>{
console.log('setTimeout1')
Promise.resolve().then(()=>{
console.log('Promise2')
})
},0)

输出结果是Promise1,setTimeout1,Promise2,setTimeout2

1. 查看微任务队列,取出微任务队列中的值,输出 Promise 1。

2. 生成一个异步任务宏任务setTimeout2。

3. 微任务队列清空,查看宏任务队列,setTimeout1在setTimeout2之前,取出setTimeout1

生成一个promise2的微任务。

清空微任务队列中的值,输出 Promise2。

4. 查看宏任务队列,输出setttimeout2。

您的支持是我们创作的动力!

网友回答文明上网理性发言 已有0人参与

发表评论: