JAVA script 循环 图片_深入分析JavaScript 事件循环(Event Loop)

事件循环(Event Loop),是每个JS开发者都会接触到的概念,但是刚接触时可能会存在各种疑惑。

众所周知,JS是单线程的,即同一时间只能运行一个任务。一般情况下这不会引发问题,但是如果我们有一个耗时较多的任务,我们必须等该任务执行完毕才能进入下一个任务,然而等待的这段时间常常让我们无法忍受,因为我们这段时间什么都不能做,包括页面也是锁死状态。

好在,时代在进步,浏览器向我们提供了JS引擎不具备的特性:Web API。Web API包括DOM API、定时器、HTTP请求等特性,可以帮助我们实现异步、非阻塞的行为。我们可以通过异步执行任务的方法来解决单线程的弊端,事件循环为此而生。

提问QAQ:为什么JavaScript是单线程的?

多个线程表示您可以同时独立执行程序的多个部分。确定一种语言是单线程还是多线程的最简单方法是看它拥有有多少个调用堆栈。JS 只有一个,所以它是单线程语言。

将JS设计为单线程是由其用途运行环境等因素决定的,作为浏览器脚本语言,JS的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。同时,单线程执行效率高。

1. Event Loop旧印象

大家熟悉的关于事件循环的机制说法大概是:主进程执行完了之后,每次从任务队列里取一个任务执行。如图所示,所有的任务分为同步任务和异步任务,同步任务直接进入任务队列-->主程序执行;异步任务则会挂起,等待其有返回值时进入任务队列从而被主程序执行。异步任务会通过任务队列的机制(先进先出的机制)来进行协调。具体如图所示:

0cqtrayvhwz.jpg

同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入任务队列。主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们所熟悉的Event Loop (事件循环)。但是promise出现之后,这个说法就不太准确了。

2. Event Loop 后印象

2.1 理论

这里首先用一张图展示JavaScript的事件循环:

128d4a45470f8fafb7d3abcf1f2fc590.png

直接看这张图,可能黑人问号已经出现在同学的脑海。。。

这里将task分为两大类,分别是macroTask(宏任务)和microTask(微任务).一次事件循环:先运行macroTask队列中的一个,然后运行microTask队列中的所有任务。接着开始下一次循环(只是针对macroTask和microTask,一次完整的事件循环会比这个复杂的多)。

那什么是macroTask?什么是microTask呢?

JavaScript引擎把我们的所有任务分门别类,一部分归为macroTask,另外一部分归为microTack,下面是类别划分:

macroTask:

setTimeout

setInterval

setImmediate

requestAnimationFrame

I/O

UI rendering

microTask:

process.nextTick

Promise

Object.observe

MutationObserver

我们所熟悉的定时器就属于macroTask,仅仅了解macroTask的机制还是不够的。为直观感受两种队列的区别,下面上代码进行实践感知。

2.2 实践

以setTimeout、process.nextTick、promise为例直观感受下两种任务队列的运行方式。

console.log('main1');

process.nextTick(function() {

console.log('process.nextTick1');

});

setTimeout(function() {

console.log('setTimeout');

process.nextTick(function() {

console.log('process.nextTick2');

});

}, 0);

new Promise(function(resolve, reject) {

console.log('promise');

resolve();

}).then(function() {

console.log('promise then');

});

console.log('main2');

别着急看答案,先以上面的理论自己想想,运行结果会是啥?

最终结果是这样的:

main1

promise

main2

process.nextTick1

promise then

// 第二次事件循环

setTimeout

process.nextTick2

process.nextTick 和 promise then在 setTimeout 前面输出,已经证明了macroTask和microTask的执行顺序。但是有一点必须要指出的是。上面的图容易给人一个错觉,就是主进程的代码执行之后,会先调用macroTask,再调用microTask,这样在第一个循环里一定是macroTask在前,microTask在后。

但是最终的实践证明:在第一个循环里,process.nextTick1和promise then这两个microTask是在setTimeout这个macroTask里之前输出的,这是因为Promises/A+规范规定主进程的代码也属于macroTask。

主进程这个macroTask(也就是main1、promise和main2)执行完了,自然会去执行process.nextTick1和promise then这两个microTask。这是第一个循环。之后的setTimeout和process.nextTick2属于第二个循环

别看上面那段代码好像特别绕,把原理弄清楚了,都一样 ~

requestAnimationFrame、Object.observe(已废弃) 和 MutationObserver这三个任务的运行机制大家可以从上面看到,不同的只是具体用法不同。重点说下UI rendering。在HTML规范:event-loop-processing-model里叙述了一次事件循环的处理过程,在处理了macroTask和microTask之后,会进行一次Update the rendering,其中细节比较多,总的来说会进行一次UI的重新渲染。

3. 小结

总而言之,记住一次事件循环:先运行macroTask队列中的一个,然后运行microTask队列中的所有任务。接着开始下一次循环。

参考文献:

JavaScript Event Loop相关原理解析

深入理解事件循环机制

JavaScript运行机制

以上就是深入分析JavaScript 事件循环(Event Loop)的详细内容,更多关于JavaScript 事件循环(Event Loop)的资料请关注聚米学院其它相关文章!

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

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

相关文章

java 方法重载的作业_java第六章 方法及方法重载 课堂笔记、作业

当参数传递为基本数据类型时,参数变化不保留,基本数据类型参数传值当参数传递为引用数据类型时,参数变化会保留,引用数据类型参数传址//基本数据类型在别处被重新赋值,则本体不受影响,其值不变//引用型数据…

java旋转图片后边上变黑_Java旋转图像将背景的一部分变成黑色

因此,我下载了“原始”图像(不是正方形),对其进行了修改,使其变为正方形,运行您的代码,得到了java.awt.image.ImagingOpException:无法转换src图像异常,将BufferedImage.TYPE_INT_RGB更改为BufferedImage .TYPE_INT_ARGB并得到…import java.awt.geom.AffineTransfo…

python 数据库连接池_【转】Python 数据库连接池

python编程中可以使用pymysql进行数据库连接及增删改查操作,但每次连接mysql请求时,都是独立的去请求访问,比较浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此实际使用中,通常会…

java 获取oracle表结构_获取Oracle中所有表的列表?

回答(19)2 years ago我们可以从以下查询获取所有表格,包括列详细信息:SELECT * FROM user_tab_columns;2 years ago使用sqlplus更好地查看如果您正在使用 sqlplus ,您可能需要首先设置一些参数以便在您的列被破坏时更好地查看(退出 sqlplus 会…

java后台处理excel_java后台利用Apache poi 生成excel文档提供前台下载示例

之前在项目中会用到在java在后台把数据填入Word文档的模板来提供前台下载,为了自己能随时查看当时的实现方案及方便他人学习我写了这篇博客,访问量已经是我写的博客里第一了。于是乎我在学会用Java在后台利用Apache poi 生成excel文档提供前台下载之后就…

宝塔php漏洞,[安全预警]关于最近宝塔闹得很厉害的PMA漏洞BUG

文章前言在2020年8月23日的下午有个憨憨管理在我群艾特全员 说宝塔爆出漏洞了赶快更新吧!影响机器需同时满足以下所有条件1、软件版本为Linux面板7.4.2 或者Windows面板6.8.02、开放888且未配置http认证,3、安装了phpmyadmin,mysql数据库不受…

求十个学生的平均成绩java,JAVA 声明一个数组,存一个学生的五门成绩。求该学生的总成绩、平均成绩。...

JAVA 声明一个数组,存一个学生的五门成绩。求该学生的总成绩、平均成绩。mip版 关注:116 答案:3 悬赏:30解决时间 2021-01-26 06:39已解决2021-01-25 17:54声明一个数组,存一个学生的五门成绩。求该学生的总成绩、平均成绩。JAVA知识最佳答案2021-01-25 18:12public class S…

php伪静态限制网页播放视频,学习猿地-php伪静态后html不能访问怎么办

php伪静态后html不能访问的解决办法:首先判断文件是否存在;然后设置存在则不rewirte,不存在且符合规则才rewrite;最后修改htaccess文件即可。具体问题:PHP伪静态后不能访问纯html文件.htaccess文件RewriteEngine onRew…

oracle binary_integer pls_integer,oracle中binaryinteger与plsinteger的区别

oracle中binaryinteger与plsinteger的区别 Oracle 中 Binary_Integer 与 Pls_Integer 的区别Binary_Integer 与 Pls_Integer 都是整型类型. Binary_Integer 类型变量值计算是由 Oracle 来执行,不会出现溢出,但是执行速度较慢,因为它是由 Orac…

梁单元分析matlab,[FEM][有限元][编程][Matlab][Code by myself] 2D Timoshenko梁单元

(有空和小伙伴一起写写有限元程序)程序作者 ( Author )JiDong Cui (崔济东)1, XueLong Shen (沈雪龙)21.广州容柏生建筑结构设计事务所;2.华南理工大学建筑设计研究院基本概念 ( Concept )欧拉梁单元基于一定的假设(Kirchhoff假设),在梁的高度远小于其跨…

oracle分组后伪列,Oracle伪列和伪表和分组函数(row_number,Rank)

oracle的伪列以及伪表oracle系统为了实现完整的关系数据库功能,系统专门提供了一组成为伪列(Pseudocolumn)的数据库列,这些列不是在建立对象时由我们完成的,而是在我们建立时由Oracle完成的。Oracle目前有以下伪列:一、伪列&#…

linux运行搜狗拼音,Linux 搜狗输入法的安装(Ubuntu版)

1、首先从搜狗官网下载搜狗输入法Linux版本的安装包2、按ctrl alt T 打开Linux终端3、安装搜狗输入法: sudo dkpg -i xxx.deb, 如果报错,主要是由于两个原因:a、权限不够,可以通过获取root权限,命令‘su’;…

2023年腾讯云轻量应用服务器测评2核2G4M带宽

腾讯云轻量应用服务器测评2核2G4M带宽88元一年,2核CPU、2G内存、3M带宽,腾讯云轻量应用服务器(Tencent Cloud Lighthouse)是一款开箱即用的云服务器产品,面向轻量应用场景,旨在为中小企业和开发者提供便捷高…

linux tcp连接计算机,计算机基础知识——linux socket套接字tcp连接分析

2016.7.4今天晚上对项目顶层文件(daemon)进行了分析,对其中的TCP连接进行具体的代码级分析。1、需求分析首先得知道我们这里为什么要用TCP连接,我们的整个测试系统是由上位机作为客户端,发送测试文件,测试命令给我们测试程序上&am…

定时器驱动数码管c语言程序,74hc595驱动数码管时间程序

74hc595驱动数码管时间程序这里是电路图:下面是51单片机驱动74hc595芯片的程序:#include //包含51单片机的头文件#include#define uint unsigned int#define uchar unsigned char//sbit sin_595 P1^0;//sbit rclk_595 P…

石油大学c语言考试答案,中石油华东2012春《C语言》在线答案

);! X" l4 d0 m5 T0 A 满分:2 分* }4 x X$ a& t, l% i3. 当对两个字符串进行比较时,应该使用的函数是A. strcat, y, Z- S p t! k! GB. strcmp2 } R% s8 P* Z/ yC. strcpy, i$ q. b5 P8 m j v1 k3 H2 W3 mD. strlen* I B S…

c语言中怎么暂停一个一个游戏,求助:最近在linux下用c语言写了一个贪吃蛇程序,有几个问题,第一:贪吃蛇怎么实现暂停,第二:有时候同时输入上下左右中的两个键就会直接游戏结束...

求助:最近在linux下用c语言写了一个贪吃蛇程序,有几个问题,第一:贪吃蛇怎么实现暂停,第二:有时候同时输入上下左右中的两个键就会直接游戏结束/*以下是主要的逻辑代码,还有些.c和.h就没发了*/#i…

android view显示隐藏动画效果,Android 根据手势顶部View自动展示与隐藏效果

首先来看一下效果:大体思路如下:总体布局用了一个自定义的ViewGroup,里面包了两个View(top View,bottomView)我在bottomView里放了ViewPager,里面又有Fragment,Fragment里放的是ListView原理:Vi…

android点击地址调用地图,Android 实现点击按钮 调用手机外部地图导航

//弹出Dialog 选择外部地图private void setMap(){final Dialog dianew AlertDialog.Builder(mContext).create();View viewLayoutInflater.from(mContext).inflate(R.layout.dialog_map, null);dia.show();dia.getWindow().setContentView(view);TextView tv_baidu(TextView) …

android webservices 返回多行多列数据,NoahWeb实现表格多行多列

用NoahWeb的表现层指令可以在动态生成的页面中非常容易的实现多行多列的表格。在正式学习以前我们需要先来了解一下怎么用NoahWeb的表现层来做动态内容显示。在NoahWeb设计器中新建或打开一项目以后,在Macromedia Dreamweaver MX 2004中新建了一个“空页面”&#x…