聊一聊宏任务与微任务

559 阅读2分钟

前言

聊宏任务与微任务之前,我们先要知道JavaScript执行机制的特点

内容

首先JavaScript是单线程的,单线程的意思就是同一个时间,只能做一件事情(不能边吃饭边玩手机),与之相反的是多线程,同一时间,可以做多件事件(可以边吃饭边玩手机)。两者相比较,当然是多线程效率更高,但JavaScript为什么要使用单线程呢?

因为JavaScript设计之初,考虑的是如何与用户交互,如何操作dom,如果是多线程的话,就会出现一种情况:先删除dom还是先增加dom。所以JavaScript比较适用单线程,也是JavaScript的一个特点,以后也不会改。

JavaScript是顺序执行的,顺序执行单线程过于死板,会出现一个问题:不能边吃饭边玩手机,必须吃完饭才能玩手机,如果一直不吃饭,就一直不能玩手机。那么JavaScript是如何解决这个问题的呢?代码:

<div id='btn'>按钮</div><script type="text/javascript">
  var btn = document.getElementById('btn')
  btn.onclick = function(){
    console.log('点击按钮')
  }
  console.log('111')
</script>

按照单线程顺序执行代码,应该是等待用户点击按钮,然后再打印111,如果不点击,就不打印111

但实际结果是没有等待用户点击,直接打印 111

因为这个原因,浏览器有了事件执行机制,浏览器在执行时,是按照 同步=》异步(微任务=》宏任务=》微任务...)的顺序执行的。

  • 同步任务:同步是依次执行,就是会将同步任务放在主线程中,形成一个栈。除了异步任务以外的都是同步任务。
  • 异步任务:setTimeoutsetIntervalajax事件绑定等。异步任务又可以分为:宏任务微任务

    • 宏任务:主代码块setTimeoutsetIntervalsetImmedia()requestAnimationFrame()

      setImmedia()node的、requestAnimationFrame()是浏览器的

    • 微任务:process.nextTick()Promise.then()catchfinallyObjectobser

代码演示:

setTimeout(function(){
  console.log('a') // 宏任务
})
​
new Promise(resolve=>{
  console.log('b') // 同步 .then()才是异步!
  resolve()
}).then(()=>{
  console.log('c')// 微任务
}).then(()=>{
  console.log('d') // 微任务
})
​
console.log('e')// 同步任务

执行顺序:b -> e -> c -> d -> a

总结

这是js的执行机制,记住执行顺序是 同步、异步,异步包括(宏任务、微任务),常见的宏任务有哪些、微任务有哪些。