首页 » 文章 » 文档 » js 异步问题 » 宏任务 macroTask 和微任务 microTask

宏任务 macroTask 和微任务 microTask

什么是宏任务,什么是微任务

  • 宏任务:setTimeout,setInterval,Ajax,DOM事件
  • 微任务:Promise async/await
  • 微任务执行时机比宏任务要(记住)
console.log(100)
// 宏任务
setTimeout(()=>{
console.log(200)
})
// 微任务
Promise.resolve().then(()=>{
console.log(300)
})
console.log(400)

// 100
// 400
// 300
// 200

event loop 和 DOM 渲染

  • JS 是单线程的,而且和 DOM 渲染共用一个线程
  • JS 执行的时候,得留一些时机供 DOM 渲染
  • 再次回归一遍 event loop 的过程
console.log('Hi')

setTimeout(function cb1(){
console.log('cb1') // cb1 即 callback
},5000)

console.log('Bye')

每次 Call Stack 清空(即每次轮询结束),即同步任务执行完;都是 DOM 重新渲染的机会,DOM 结构如有改变则重新渲染;然后再去触发下一次 Event Loop

const p = '<p>一段文字</p><p>一段文字</p><p>一段文字</p>'
document.getElementById('container').innerHTML = p

// length 3
console.log('length',document.getElementById('container').children.length)
// (alert 会阻断 js 执行,也会阻断 DOM 渲染,便于查看效果)
alert('本次 call stack 结束,DOM 结构已更新,但尚未触发渲染')

微任务和宏任务的区别

  • 宏任务:DOM 渲染后触发,如 setTimeout
  • 微任务:DOM 渲染前触发,如 Promise,代码演示:
const p = '<p>一段文字</p><p>一段文字</p><p>一段文字</p>'
document.getElementById('container').innerHTML = p

// 微任务:DOM 渲染前触发
Promise.resolve().then(()=>{
// length1 3
console.log('length1',document.getElementById('container').children.length)
alert('Promise then') // DOM 渲染了吗? - No
})


// 宏任务:DOM 渲染后触发
setTimeout(()=>{
// length2 3
console.log('length2',document.getElementById('container').children.length)
alert('setTimeout') // DOM 渲染了吗? - Yes
})

从 event loop 解释,为何微任务执行更早

  • 微任务是 ES6 语法规定的
  • 宏任务是由浏览器规定的

»js 异步问题

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Scroll to Top