【JS】事件循环机制

一、JS单线程、异步、同步概念

  众所周知,JS是单线程(如果一个线程删DOM,一个线程增DOM,浏览器傻逼了~所以只能单着了),虽然有webworker酱紫的多线程出现,但也是在主线程的控制下。webworker仅仅能进行计算任务,不能操作DOM,所以本质上还是单线程。

  单线程即任务是串行的,后一个任务需要等待前一个任务的执行,这就可能出现长时间的等待。但由于类似ajax网络请求、setTimeout时间延迟、DOM事件的用户交互等,这些任务并不消耗 CPU,是一种空等,资源浪费,因此出现了异步。通过将任务交给相应的异步模块去处理,主线程的效率大大提升,可以并行的去处理其他的操作。当异步处理完成,主线程空闲时,主线程读取相应的callback,进行后续的操作,最大程度的利用CPU。此时出现了同步执行和异步执行的概念,同步执行是主线程按照顺序,串行执行任务;异步执行就是cpu跳过等待,先处理后续的任务(CPU与网络模块、timer等并行进行任务)。由此产生了任务队列与事件循环,来协调主线程与异步模块之间的工作。

二、事件循环机制

                                  事件循环示例图

  如上图为事件循环示例图(或JS运行机制图),流程如下:

    step1:主线程读取JS代码,此时为同步环境,形成相应的堆和执行栈;

    step2:  主线程遇到异步任务,指给对应的异步进程进行处理(WEB API);

    step3:  异步进程处理完毕(Ajax返回、DOM事件处罚、Timer到等),将相应的异步任务推入任务队列;

    step4: 主线程执行完毕,查询任务队列,如果存在任务,则取出一个任务推入主线程处理(先进先出);

    step5: 重复执行step2、3、4;称为事件循环。

  执行的大意:

    同步环境执行(step1) -> 事件循环1(step4) -> 事件循环2(step4的重复)…

  其中的异步进程有:

    a、类似onclick等,由浏览器内核的DOM binding模块处理,事件触发时,回调函数添加到任务队列中;

    b、setTimeout等,由浏览器内核的Timer模块处理,时间到达时,回调函数添加到任务队列中;

    c、Ajax,由浏览器内核的Network模块处理,网络请求返回后,添加到任务队列中。

三、任务队列

  如上示意图,任务队列存在多个,同一任务队列内,按队列顺序被主线程取走;不同任务队列之间,存在着优先级,优先级高的优先获取(如用户I/O);

  3.1、任务队列的类型

    任务队列存在两种类型,一种为microtask queue,另一种为macrotask queue。

    图中所列出的任务队列均为macrotask queue,而ES6 的 promise[ECMAScript标准]产生的任务队列为microtask queue。

            

  3.2、两者的区别

    microtask queue:唯一,整个事件循环当中,仅存在一个;执行为同步,同一个事件循环中的microtask会按队列顺序,串行执行完毕;

    macrotask queue:不唯一,存在一定的优先级(用户I/O部分优先级更高);异步执行,同一事件循环中,只执行一个。

  3.3、更完整的事件循环流程    

    将microtask加入到JS运行机制流程中,则:

      step1、2、3同上,

      step4:主线程查询任务队列,执行microtask queue,将其按序执行,全部执行完毕;

      step5:主线程查询任务队列,执行macrotask queue,取队首任务执行,执行完毕;

      step6:重复step4、step5。

    microtask queue中的所有callback处在同一个事件循环中,而macrotask queue中的callback有自己的事件循环。

    简而言之:同步环境执行 -> 事件循环1(microtask queue的All)-> 事件循环2(macrotask queue中的一个) -> 事件循环1(microtask queue的All)-> 事件循环2(macrotask queue中的一个)...

    利用microtask queue可以形成一个同步执行的环境,但如果Microtask queue太长,将导致Macrotask任务长时间执行不了,最终导致用户I/O无响应等,所以使用需慎重。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/292608.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

京东tp26旋转验证

记录一下,狗东的tp26旋转验证码,难点还是在这个轨迹上。我真的是一点都不喜欢玩轨迹!!!! 类似于百度旋转的图,不过他这个东西还是稍微有点差距的。 鉴于生病了脑子不太好使,就不过多…

KBU808-ASEMI适配高端电源KBU808

编辑:ll KBU808-ASEMI适配高端电源KBU808 型号:KBU808 品牌:ASEMI 封装:KBU-4 最大平均正向电流:8A 最大重复峰值反向电压:800V 产品引线数量:4 产品内部芯片个数:4 产品内…

Docker概述及介绍

Docker是近年来新兴的虚拟化工具,它可以和虚拟机一样实现资源和系统环境的隔离。 库,然后再安装应用; Container(Docker容器),在宿主机器、宿主机器操作系统上创建Docker引擎,在引擎的基础上再安装应用。 Docker三…

链表反转【思路】

链表反转 思路1. 将1->2->3->4->5这个链表中的2,3位置反转为1->3->2->4->52. 将1->2->3->4->5这个链表中的2,3,4位置反转为1->4->3->2->5思路总结 3. 将1->2反转为2->1 Java代码 将1-…

VM——计算流程执行耗时

1、计算同一个流程内的耗时,可以直接用“耗时统计”模块; 2、计算多个流程的运行耗时,需要使用“脚本”,利用C#函数计算耗时 首先,记录起始时间,保存到string类型的全局变量中, curTmStr Dat…

c++学习笔记-提高篇-STL标准模板库3(stack容器、queue容器以及list容器)

目录 Stack容器 一、Stack容器介绍 二、stack常用接口 三、栈的示例 queue(队列)容器 一、queue容器介绍 二、queue常用接口 三、queue示例 list容器 一、list容器介绍 二、list常用接口及示例 (一)list构造函数 &am…

HTML---盒子模型

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一.盒子模型概述 HTML中的盒子模型是一种用于描述和布局元素的概念。每个 HTML 元素都可以被表示为一个矩形的盒子,这个盒子包括四个部分:内容区域、内边距、边框和外边距…

【终极教程】Cocos2dx服务端重构(优化cocos2dx服务端)

文章目录 概述问题概述1. 代码混淆代码加密具体步骤测试和配置阶段IPA 重签名操作步骤2. 缺乏文档3. 缺乏推荐的最佳实践4. 性能问题 总结 概述 Cocos2dx是一个非常流行的跨平台游戏引擎,开发者可以使用这个引擎来开发iOS、Android和Web游戏。同时,Coco…

python的*和两个* *的区别,python中连续两个小于号

本篇文章给大家谈谈python两个等于号和一个等于号的区别,以及python为什么用两个等于号,希望对各位有所帮助,不要忘了收藏本站喔。 原帖地址见:[Python]-12-星号变量的特殊用法 在Python中,星号除了用于乘法数值运算和…

影响晶振频率稳定性的因素及解决方法

晶振作为电子设备中的核心元件,其频率稳定性对设备的性能和可靠性具有重要影响。晶发电子将介绍影响晶振频率稳定性的因素,并探讨相应的解决方法。 一、影响晶振频率稳定性的因素 频率:晶振的频率是影响其性能的最重要因素之一。在选择晶振…

Appearance-Motion Memory Consistency Network for Video Anomaly Detection 论文阅读

Appearance-Motion Memory Consistency Network for Video Anomaly Detection 论文阅读 AbstractIntroductionRelated WorkMethodExperimentsConclusions阅读总结 论文标题:Appearance-Motion Memory Consistency Network for Video Anomaly Detection 文章信息&am…

3分钟看懂如何给开源项目发起提案

背景 前段时间在使用 Pulsar 的 admin API 时,发现其中的一个接口响应非常慢: admin.topics().getPartitionedStats(topic); 使用 curl 拿到的响应结果非常大,同时也非常耗时: 具体的 issue 在这里:https://github.…