APP下载

浏览器中的事件处理机制研究

2020-12-28陆柳杰

电脑知识与技术 2020年31期
关键词:同步

陆柳杰

摘要:该文主要是通过对浏览器中用户操作、事件循环机制、任务队列的分析来研究浏览器环境中JavaScript的内部执行机制,包括请求的发送,页面的渲染过程,函数的执行过程等。最终得出同步任务先于异步任务执行,微任务先于宏任务执行的结论。

关键词:同步;异步;事件循环;任务队列;Promise

中图分类号:TP391      文献标识码:A

文章编号:1009-3044(2020)31-0066-03

1 引言

JavaScript(JS)是动态编程语言。利用HTML/CSS/JS,可以做出动态交互的网站。由布兰登·艾克(Brendan Eich,Mozilla基金会、Mozilla项目和Mozilla公司的联合创始人)发明[1]。虽然JavaScript的语法非常简洁灵活,但是JavaScript的应用场合极其广泛,可以做PPT、照片库、浮动布局和响应按钮点击,复杂到游戏、2D/3D 动画、大型数据库驱动程序等等。开发者们基于JavaScript核心编写了大量开源的实用工具,提高了開发效率。其中包括:

1)浏览器内置的API提供了丰富的功能,比如:动态创建HTML和设置CSS样式、生成3D图像与音频样本、从用户的摄像头采集处理视频流等等。

2)开发人员在开发站点的时候可以利用已有的一些功能优化自己的站点。

3)需要快速创建网站的时候可以利用一些现有开源的框架和库。

JavaScript的一大特点就是单线程,单线程是指同一时间段只能处理一件任务,其他的任务都要排队[2]。JavaScript的核心功能是方便用户通过点击等DOM操作与机器交互。

浏览器要处理页面渲染,交互事件,还有各种用户输入,任务很多,但是这么多任务又只能在一个主线程中执行,必须有条不紊的执行才不会发生阻塞。所以就需要一个机制来帮助浏览器执行这一系列任务。这就是任务调度系统,也就是我们接下来要讲的Eventloop。

2 浏览器基本工作原理

2.1 浏览器基本介绍

浏览器对JS的解析执行是单线程的,并且是按一定的顺序执行的。然而在Javascript中又有异步的概念,但是这两者并不冲突。因为除了解析JS代码的引擎,浏览器中还有其他很多的引擎,解析JS的引擎被叫作主线程。还有一些事用户界面渲染引擎,浏览器内核引擎,呈现引擎,网络引擎,JavaScript解释器。

用户在网页上能看到的东西都属于用户界面,除了浏览器中控制台的部分。浏览器引擎(浏览器内核)是用户界面和呈现引擎之间的纽带,主要负责一些指令的传送。呈现引擎负责显示代码,如果代码是HTML格式的,呈现引擎就会解释代码的HTML标签和CSS样式,最终将一个静态页面显示在浏览器中。通常有网络请求的地方就会用到浏览器中的网络引擎,比如当用户发送HTTP或者HTTPS请求的时候。用户界面上有按钮,表单,链接,图片,文字等各种资源。浏览器会提供一些通用的接口,供用户调用。用于解析和执行JavaScript代码是JavaScript解释器。最后一点不会经常用到,但还是有必要说明,数据存储属于浏览器中的持久层。由于浏览器会在硬盘上存储一些缓存,所以需要数据存储这一层。新出的HTML5规范定义了一个浏览器内部数据库,方便存储一些用户临时数据。使用起来很轻便。

2.2 浏览器引擎

浏览器引擎是多线程的,基本包含页面渲染线程,JavaScript引擎线程,定时触发器线程,事件触发线程,异步http线程等。页面渲染线程,主要是用来渲染html文件。JavaScript引擎线程是可以处理页面节点的渲染。定时触发器线程主要是用于某些需要定时触发的任务。当我们需要执行异步操作,比如发送AJAX请求,并且需要数据实时回填的时候,就会用到浏览器的事件触发线程。同时AJAX请求发送时浏览器会开一个新的线程,只要检测到服务端有数据返回,就开始执行异步回调里面的回调函数,暂时不能执行的就需要放到队列中等待后续通知执行。

JavaScript引擎和可视化引擎是不能同时运行的,不能在操作dom的同时渲染页面。那么执行顺序必然是有先后,所以Javascript引擎会有一个事件监测的功能,会不停地取的检查js引擎的主线程是否已经执行完,并且将执行栈清空。只要当前执行栈被清空了,就会通知主线程执行下一个任务。

2.3 Javascript引擎执行机制

由于js的运行环境是单线程的,所以执行其他的异步操作必须利用浏览器来的其他线程来实现。其中最主要的是运用了浏览器的事件触发线程和js引擎线程,开启相关的网络服务和定时器也会用到其他的线程。具体流程如图1所示。当一段任务开始执行的时候,Javascript引擎先判断这段代码是否属于异步代码,如果是同步代码,就先按顺序执行同步代码,如果是异步代码就把它放入任务队列中,等待同步代码执行完,再从任务队列中取出执行。

3 任务队列运行流程

3.1 单线程

Javascript在浏览器中的运行是单线程,当前任务没有执行完必然会阻塞下一个任务的执行。然而浏览器是由事件驱动的,浏览器中存在很多异步行为。Javascript单线程引擎是解析它的任务队列的,比如浏览器点击事件,Ajax请求,回调函数都是异步的,所以会被放入到执行队列中。

3.1.1  同步异步

同步任务在主线程上执行的时候不能插入其他同步任务,必须等当前任务执行完才能执行下一个任务,如果AJAX请求是同步的,服务器数据一直不返回就会引起阻塞。所以这个时候就需要异步任务。

异步任务在同步任务没有执行完的时候,是不会进入主线程的,会暂时进入任务队列排队,只有当主线程中的同步任务都执行完,主线程才会通知任务队列,异步任务可以执行了,并且从队列中取出位于第一的任务进入主线程中执行。

猜你喜欢

同步
素质教育理念下艺术教育改革的思路
政府职能的转变与中国经济结构调整的同步
“四化”同步发展的实证检验及实现路径研究
冠修复与根管同步治疗隐裂牙牙髓病的临床研究
时间统一系统秒同步故障远程预警系统设计
基于CAZAC序列的MIMOOFDM定时同步算法