宏任务和微任务
Chunbin Lv3

异步回调的概念

异步回调有两种方式

  1. 把异步回调函数封装成一个宏任务,添加到消息队列尾部,当循环系统执行到该任务的时候执行回调函数–如 setTimeout 和 XMLHttpRequest的回调函数
  2. 主函数执行结束后,当前宏任务结束之前执行回调函数,这通常都是微任务

宏任务

宏任务类型

  • 渲染事件(解析DOM、计算布局、绘制)
  • 用户交互事件(鼠标点击、滚动页面、放大缩放等)
  • js脚本执行事件
  • 网络请求完成、文件读写完成事件
  • setTimeout setInterval

定义

为了协调这些任务有条不紊地在主进程执行,引入了消息队列和事件事件循环
渲染进程内部维护多个消息队列,比如延迟执行队列普通的消息队列
然后主进程采用一个for循环,不断地从这些任务队列中取出任务并执行任务。
这些就是宏任务

事件循环的流程

  • 先从多个消息队列中选出一个最老的任务,这个任务称为oldestTask;
  • 然后循环系统记录任务开始执行的事件,并把这个oldestTask设置为当前正在执行的任务;
  • 当任务执行完成之后,删除当前正在执行的任务,并从对应的消息队列中删除这个oldestTask;
  • 最后统计执行完成的时长等信息

宏任务的缺点

  1. 难以胜任时间精度要求高的场景
    1
    2
    3
    4
    5
    6
    7
    8
    function timerCallback2(){
    console.log(2)
    }
    function timerCallback(){
    conole.log(1)
    setTimeout(timerCallback2,0)
    }
    setTimeout(timerCallback,0)
    以上代码:
    在调用setTimeout来设置回调任务的间隙,消息队列中就有可能就被插入很多系统级的任务。导致第二次的setTimeout可能延后很多

微任务

定义:微任务就是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前

如何运转

V8创建一个全局执行上下文,同时创建一个微任务队列。这个微任务队列是给V8引擎内部使用的,所以你无法通过js直接访问。

如何产生微任务

MutationObserver

监控某个节点,然后通过js修改这个节点,或者为这个节点添加删除部分子节点,当DOM节点发生变化时,就会产生DOM节点变化记录的微任务

Promise

当调用 Promise.resolve() 或者 Promise.reject() 的时候,也会产生微任务。

执行时机

当前宏任务中的javaScript快要执行完成时,js引擎准备退出全局执行上下文并清空调用栈的时候,js引擎会检查全局执行上下文中的微任务队列,按顺序执行。ps:还有别的检查点

由 Hexo 驱动 & 主题 Keep
访客数 访问量