搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解

此篇文章为学习慕课网双越老师课程所写自学笔记,如有侵权,立即删除

文章目录

    • 先看一到面试题
    • 什么是宏任务和微任务
    • event loop 和DOM渲染
      • 用event loop执行下面代码的过程
      • DOM渲染的时机
    • 为什么微任务比宏任务执行更快
    • 微任务和宏任务的根本区别

先看一到面试题

下面代码console.log的执行顺序

console.log(100);

setTimeout(()=>{
     
    console.log(200);
})


setTimeout(()=>{
     
    console.log(201);
})


Promise.resolve().then(()=>{
     
    console.log(300);
})

console.log(400);


// 100 400 300 200


// 为什么300比200先打印


为什么300比200先打印这里就引出了宏任务和微任务

什么是宏任务和微任务

搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第1张图片

  • 宏任务包括:setTimeout setInterval Ajax DOM事件
  • 微任务:Promise async/await
  • 微任务比宏任务的执行时间要早

event loop 和DOM渲染

用event loop执行下面代码的过程

搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第2张图片
先到call stack执行第一行代码打印Hi
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第3张图片
执行setTimeout时候是将定时器放到webAPIs中
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第4张图片
最后马上打印出bye
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第5张图片

这时候就马上启用eventlog的机制,一遍一般的启用callback queue

搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第6张图片

DOM渲染的时机

其实在上面的执行过程中 我们还漏掉了一步 DOM的渲染
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第7张图片
由图可知,同步代码全部执行完成后,call stack空闲了 就会马上进行DOM的渲染,触发了eventlop之后,我们会把cb1放到call stack里面去 有会触发DOM的渲染

为什么微任务比宏任务执行更快

先看下面一段代码
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第8张图片
上面代码alert执行前刚好只会改变DOM的结构,但不会触发渲染只有点击alert的确定后页面才会渲染出变化

  • 宏任务的发生是在DOM渲染后触发,如setTimeout
  • 而微任务是在DOM渲染前触发,如Promise

看下面代码的执行过程就明白了

const $p1 = $('

一段文字

'
) const $p2 = $('

一段文字

'
) const $p3 = $('

一段文字

'
) $('#container') .append($p1) .append($p2) .append($p3) // console.log('length',$('container').children().length); // alert('本次 call stack 结束,DOM结构已更新,但尚未触发渲染') Promise.resolve().then(()=>{ console.log('length1', $('#container').children().length ); alert('Promise then')//DOM还没有触发,点击确定就会立即触发 }) setTimeout(()=>{ console.log('length2', $('#container').children().length); alert('setTime out')//DOM已经渲染了 })

微任务和宏任务的根本区别

在执行setTimeout 的时候
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第9张图片
是把定时器放到web APIs 里面

但是如果是Promise.then()的时候 会把它放到一个叫micro task queue的里面,而不是放到web APIs里面,如下图
搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第10张图片

为什么会有这个规定了

搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第11张图片

所以之前的执行步骤最终变为

搞清js异步的重要一步---宏任务(marcroTask)和微任务(microTask)--精细讲解_第12张图片

  1. 先是将所有同步代码执行完毕后,call back清空
  2. 然后执行当前的微任务
  3. 再尝试DOM的渲染
  4. 最后触发Event Loop

你可能感兴趣的:(javascript)