zoukankan      html  css  js  c++  java
  • 宏任务和微任务

    微任务到底是什么?

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

    微任务有什么用?

    微任务可以在实时性和效率之间做一个有效的权衡。

    基于微任务的技术有哪些?

    MutationObserver、Promise 以及以 Promise 为基础开发出来的很多其他的技术。

    宏任务有哪些?

    凡是在主线程上执行的任务都是宏任务。包括:

    • 渲染事件(如解析 DOM、计算布局、绘制);

    • 用户交互事件(如鼠标点击、滚动页面、放大缩小等);

    • JavaScript 脚本执行事件;

    • 网络请求完成、文件读写完成事件。

    WHATWG规范中是如何定义事件循环机制的?

    先从多个消息队列中选出一个最老的任务,这个任务称为 oldestTask;

    然后循环系统记录任务开始执行的时间,并把这个 oldestTask 设置为当前正在执行的任务;

    当任务执行完成之后,删除当前正在执行的任务,并从对应的消息队列中删除掉这个oldestTask;

    最后统计执行完成的时长等信息。

    为什么宏任务难以满足对时间精度要求较高的任务?

    因为页面的渲染事件、各种IO的完成事件、执行JavaScript脚本的事件、用户交互的事件等都随时有可能被添加到消息队列中,而且添加事件是由系统操作的,JavaScript代码不能准确掌控任务要添加到队列中的位置,控制不了任务在消息队列中的位置,所以很难控制开始执行任务的时间。setTimeout函数触发的回调函数都是宏任务,如图所示:一旦中间插入别的任务,就会影响后面任务的执行。

    ![image-20201028143424051](/Users/zhoupanpan/Library/Application Support/typora-user-images/image-20201028143424051.png)

    微任务是如何产生的?给谁使用?

    当JavaScript执行一段脚本时,V8会为其创建一个全局执行上下文,创建的同时,V8也会在内部创建一个微任务队列用来存放微任务。

    微任务队列是给V8引擎内部使用的,无法通过JavaScript直接访问。

    微任务如何产生?
    • 使用 MutationObserver 监控某个 DOM 节点,然后再通过 JavaScript 来修改这个节点,或者为这个节点添加、删除部分子节点,当 DOM 节点发生变化时,就会产生 DOM 变化记录的微任务

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

    微任务队列何时被执行?

    在当前宏任务中的 JavaScript 快执行完成时,也就在 JavaScript 引擎准备退出全局执行上下文并清空调用栈的时候,JavaScript 引擎会检查全局执行上下文中的微任务队列,然后按照顺序执行队列中的微任务。WHATWG 把执行微任务的时间点称为检查点。

    关于微任务的结论有哪些?
    • 微任务和宏任务是绑定的,每个宏任务在执行时,会创建自己的微任务队列。
    • 微任务的执行时长会影响到当前宏任务的执行时长。因此写代码时要注意控制微任务的执行时长
    • 在一个宏任务中,分别创建一个用于回调的宏任务和微任务,无论什么情况下,微任务都早于宏任务执行
    监听DOM变化技术方案的演化史是怎样的?
    • 轮询检测

    方式:使用setTimeout和setinterval来定时检测DOM是否有改变

    问题:1、如果时间间隔设置过长,DOM变化响应不够及时;2、果果时间间隔设置过短,会浪费很多无用的工作量去检查DOM,会让页面变得低效。

    • Mutation Even

    方式:采用了观察者的设计模式,当DOM有变动就会立刻触发相应的事件,这种方式属于同步回调。

    优点:解决了实时性的问题。因为 DOM 一旦发生变化,就会立即调用JavaScript 接口

    缺点:但也正是这种实时性引发了严重的性能问题,导致动画卡顿等。

    • MutationObserver

    1、如何缓解性能问题?

    将响应函数改成异步调用,等多次DOM变化后,一次触发异步调用,而非每次调用。并且使用一个数据结构来记录期间所有的DOM变化,以此减少对性能的影响。

    2、如何保持消息通知的及时性?

    通过微任务。每次DOM节点发生变化的时候,渲染引擎将变化记录封装成微任务,并将微任务添加进当前的微任务队列中。这样当执行到检查点的时候,V8引擎就会按照顺序执行微任务了。

    综上所述: MutationObserver 采用了“异步 + 微任务”的策略。

    通过异步操作解决了同步操作的性能问题

    通过微任务解决了实时性的问题

  • 相关阅读:
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 连号区间数
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Java实现 蓝桥杯 历届试题 大臣的旅费
    Navicat查询哪些表有指定字段名
  • 原文地址:https://www.cnblogs.com/zpsakura/p/13891201.html
Copyright © 2011-2022 走看看