宏任务与微任务

87 阅读1分钟

所谓macroTask(宏任务)是指将任务排到下一个事件循环,microTask(微任务)是指将任务排到当前事件循环的队尾,执行时机会被宏任务更早。Promise的标准里没有规定Promise里的异步该使用哪种,但在node和浏览器的实现里都是使用的miroTask(微任务)

image.png

setTimeout(() => { console.log(1); }, 0) let p = Promise.resolve(2) p.then((val) => { console.log(val); })

宏任务api包括:setTimeout,setInterval,setImmediate(Node),requestAnimationFrame(浏览器),各种IO操作,网络请求

微任务api包括:process.nextTick(Node),MutationObserver(浏览器)

MutaionObserver演示:

let observer = new MutationObserver(()=>{ console.log(1); }) let node = document.createElement('div') observer.observe(node, { // 监听节点 childList: true // 一旦改变则触发回调函数 nextTickHandler }) node.innerHTML = 1

利用MutaionObserver封装一个微任务执行函数

let nextTick = (function () { let callbacks = [] function nextTickHandler() { let copies = callbacks.slice(0) callbacks = [] for (let i = 0; i < copies.length; i++) { copiesi } }

let counter = 1 let observer = new MutationObserver(nextTickHandler) // 声明 MO 和回调函数 let node = document.createElement('div') observer.observe(node, { // 监听节点 childList: true // 一旦改变则触发回调函数 nextTickHandler }) return function (cb) { callbacks.push(cb) counter = (counter + 1) % 2 //让节点内容文本在 1 和 0 间切换 node.innerHTML = counter } })()

小例题:

console.log(1)
​
setTimeout(function() {
    console.log(2)
}, 0)
​
console.log(3)

宏任务: 主线程代码, setTimeout 等属于宏任务, 上一个宏任务执行完, 才会考虑执行下一个宏任务

微任务: promise .then .catch的需要执行的内容, 属于微任务, 满足条件的微任务, 会被添加到当前宏任务的最后去执行

image.png 事件循环队列 eventLoop

image.png

例题1:

  console.log(1)
​
  setTimeout(function() {
    console.log(2) // 宏任务
  }, 0)
​
  const p = new Promise((resolve, reject) => {
    resolve(1000)
  })
  p.then(data => {
    console.log(data)  // 微任务
  })
​
  console.log(3)

image.png 例题2:

async function fn () {
  console.log(111)
}
fn()
console.log(222)

例题3:

async function fn () {
  const res = await 2
  console.log(res)
}
fn()
console.log(222)

例题4:

async function fn () {
  console.log('嘿嘿')
  const res = await fn2()
  console.log(res)  // 微任务
}
async function fn2 () {
  console.log('gaga')
}
fn()
console.log(222)

image.png