事件循环

事件循环不仅仅包含事件队列,而是具有至少两个队列,除了事件,还要保持浏览器执行的其他操作。这些操作被称为任务,并且分为两类:宏任务(或通常称为任务)和微任务。
单次循环迭代中,最多处理一个宏任务(其余的在队列中等待),而队列中的所有微任务都会被处理。当微任务队列处理完成并清空时,事件循环会检查是否需要更新UI渲染,如果是,则会重新渲染UI视图。至此,当前事件循环结束。

事件循环基于两个基本原则:
一次处理一个任务。
一个任务开始后直到运行完成,不会被其他任务中断。

两类任务队列都是独立于事件循环的,这意味着检测和添加任务的行为,是独立于事件循环完成的。
因为JavaScript基于单线程执行模型,所以这两类任务都是逐个执行的。当一个任务开始执行后,在完成前,中间不会被任何其他任务中断。除非浏览器决定中止执行该任务,例如,某个任务执行时间过长或内存占用过大。
所有微任务会在下一次渲染之前执行完成,因为它们的目标是在渲染前更新应用程序状态。
浏览器通常会尝试每秒渲染60次页面,以达到每秒60帧(60 fps)的速度。在页面渲染时,任何任务都无法再进行修改。如果想要实现平滑流畅的应用,,单个任务和该任务附属的所有微任务,都应在16ms内完成。

宏任务

宏任务的例子很多,包括创建主文档对象、解析HTML、执行主线(或全局)JavaScript代码,更改当前URL以及各种事件,如页面加载、输入、网络事件和定时器事件。从浏览器的角度来看,宏任务代表一个个离散的、独立工作单元。运行完任务后,浏览器可以继续其他调度,
如重新渲染页面的UI或执行垃圾回收。

常见的宏任务有:setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering.

宏任务场景实例

主线程JavaScript代码执行时间需要15ms。
第一个单击事件处理器需要运行8ms。
第二个单击事件处理器需要运行5ms。

假设用户在代码执行后5ms时单击第一个按钮,随后在12ms时单击第二个按钮。

执行情况:
1、[0ms]执行主线程
2、[5ms]第一个单击事件加入队列,不影响主线程
3、[12ms]第二个单击事件加入队列,不影响主线程
4、[15ms]主线程结束,从队列中移除。执行第一个单击事件
5、[23ms]第一个单击事件结束,从队列中移除。执行第二个单击事件
6、[28ms]第二个单击事件结束,从队列中移除。队列为空

微任务

而微任务是更小的任务。微任务更新应用程序的状态,但必须在浏览器任务继续执行其他任务之前执行,浏览器任务包括重新渲染页面的UI。微任务的案例包括promise回调函数、DOM发生变化等。微任务需要尽可能快地、通过异步方式执行,同时不能产生全新的微任务。微任务使得我们能够在重新渲染UI之前执行指定的行为,避免不必要的UI重绘,UI重绘会使应用程序的状态不连续。

常见的微任务有:process.nextTick, Promises, Object.observe, MutationObserver

微任务场景实例

主线程JavaScript代码执行时间需要15ms。
第一个单击事件处理器需要运行8ms。
包含立即兑现的promise,并需要运行4ms的传入回调函数。
第二个单击事件处理器需要运行5ms。

假设用户在代码执行后5ms时单击第一个按钮,随后在12ms时单击第二个按钮。

执行情况:
1、[0ms]执行主线程
2、[5ms]第一个单击事件加入队列,不影响主线程
3、[12ms]第二个单击事件加入队列,不影响主线程
4、[15ms]主线程结束创建但不执行第一个单击事件。立即兑现promise,进入微任务队列。
5、[23ms]从微任务队列挑选任务并执行,检查微任务队列,微任务都执行完毕后。执行第一个单击事件,从队列中移除。
6、[27ms]微任务队列为空,事件循环重新处理宏任务,执行第二个单击事件。
7、[32ms]第二个单击事件结束,从队列中移除。队列为空.

微任务队列中含有微任务,不论队列中等待的其他任务,微任务都将获得优先执行权。

参考资料:
《JavaScript忍者秘籍第二版》
https://html.spec.whatwg.org/multipage/webappapis.html#task-queue

JavaScript事件循环机制的更多相关文章

  1. 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)

    JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...

  2. javascript事件循环机制 浅尝手记

    引入 众所周知Javascript是一个单线程的机制,虽然可以依托多线程的浏览器实现页面如何实现页面复杂的渲染.事件响应,但仍不会改变其单线程的本质:所以对于js的事件循环机制的了解是一个前端人员的必 ...

  3. 深入理解JavaScript事件循环机制

    前言 众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心.可看HTML规范中的这段话: To ...

  4. 深入浅出Javascript事件循环机制

    一.JS单线程.异步.同步概念 众所周知,JS是单线程(如果一个线程删DOM,一个线程增DOM,浏览器傻逼了-所以只能单着了),虽然有webworker酱紫的多线程出现,但也是在主线程的控制下.web ...

  5. 浏览器中的JavaScript事件循环机制

    浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中 ...

  6. javaScript 事件循环机制

    JavaScript是单线程的编程语言,只能同一时间内做一件事.但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这就是因为JS有事件循环机制. 事件循环流程总结 主线程开始执行一段代码, ...

  7. JS JavaScript事件循环机制

    区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...

  8. 一道面试题引发对javascript事件循环机制(Event Loop)的 思考(这里讨论针对浏览器)

  9. JS浏览器事件循环机制

    文章来自我的 github 博客,包括技术输出和学习笔记,欢迎star. 先来明白些概念性内容. 进程.线程 进程是系统分配的独立资源,是 CPU 资源分配的基本单位,进程是由一个或者多个线程组成的. ...

随机推荐

  1. 10-PI开发手册-ERP发布服务供外围系统调用(RFC类型)

      一.      文档信息 版本号* 更新日期* 姓名* 更新内容及更新理由* 备注* V1.0 2019/02/19 fanjb 文档创建 以福利接口13589(Z00HRJ_GJJ_REV_FI ...

  2. Neutron:Firewall as a Service(FWaaS)

    用户可以用它来创建和管理防火墙,在 subnet 的边界上对 layer 3 和 layer 4 的流量进行过滤.   传统网络中的防火墙一般放在网关上,用来控制子网之间的访问. FWaaS 的原理也 ...

  3. idea 连接redis 出现 Caused by: java.net.SocketTimeoutException: connect timed out

    Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: java.n ...

  4. MySQL安装后无法用root用户访问的问题

    今天在换了Ubuntu后装个本地的mysql,安装过程没什么好说的:sudo apt-get install mysql-server 安装好了之后我做了以下一系列常规动作: 1.$sudo mysq ...

  5. python 学习三

    list循环删除下标会出错 L = [1,1,1,2,3,4,5]#list是根据下标来取值 #下标0,1,2,3,4,5,6 循环后下标错位 输出的结果是[1,2,4],把1也取到了 #l2 = [ ...

  6. html2canvas 识别 svg 解决方案

    参考: 预览地址 http://jsfiddle.net/bv16o50f/1/ html <div class="visualization"> <svg xm ...

  7. web自动化框架如何设计

    web自动化框架如何设计po模式总结: 1. 页面对象模型:当页面特别多的时候,代码更好的维护 2. Po是pageObject设计模式,用来管理和维护一组web元素的对象库 3. 每一个page c ...

  8. python并发编程之多线程基础知识点

    1.线程理论知识 概念:指的是一条流水线的工作过程的总称,是一个抽象的概念,是CPU基本执行单位. 进程和线程之间的区别: 1. 进程仅仅是一个资源单位,其中包含程序运行所需的资源,而线程就相当于车间 ...

  9. [SDOI2017]天才黑客

    题目大意 给一张有向图,再给一颗字典树,有向图上的每条边有一个非负边权还有一个字典树上的字符串,从一条边到另一条边的代价是那条边的边权和这两个字符串的最长公共前缀,问从1到其他点的最短路. 题解 一看 ...

  10. LOJ#2244 起床困难综合症

    解:m = 0的部分分,直接模拟.有and 0的部分分,直接模拟.<=1000的部分分,枚举攻击力之后模拟.所有操作相同的部分分,可以合并成只有一个操作.然后枚举m或者逐位贪心. 正解是逐位贪心 ...