浅谈JavaScript事件循环机制EventLoop
今天简单说下js的事件循环机制,我们都知道,javascript是单线程语言,它的核心,也是因为它的单线程。
有很多小白不清楚EventLoop到底是什么,按照中文翻译,就是事件循环,那js到底是怎样将同步和异步进行处理的。
这篇文章,就简单说一说,js的单线程处理,也就是同步和异步的代码是怎样走向的。
一、同步和异步:
所有的线程,都是有同步队列,和异步队列,立即执行的任务队列,这些都是属于同步任务,比如一个简单的函数;那么像请求接口发送ajax,发送promise,或时间计时器等等,这些就是异步任务。
二、任务队列-事件循环:
同步任务会立刻执行,进入到主线程当中,异步任务会被放到任务队列(Event Queue)当中。Event Queue 单词的意思就是任务队列。
等待同步代码执行完毕后,返回来,再将异步中的任务放到主线程中执行,反复这样的循环,这就是事件循环。也就是先执行同步,返回来按照异步的顺序再次执行
我们看下面这个代码会打印出什么:
console.log('开始111'); setTimeout(function() { console.log('setTimeout111'); }, 0); Promise.resolve().then(function() { console.log('promise111'); }).then(function() { console.log('promise222'); }); console.log('开始222');
我们猜想一下上面的代码,会怎样打印?我们知道,肯定是先走同步的代码,从上往下,先打印 “开始111”,再打印“开始222”。
中途的三个异步,进入到了异步队列,等待同步执行完(打印完),返回来再执行异步,所以是后打印出来。
打印的结果先放一放,我们稍后回来再说。现在我们中途插播一段知识点:
三、宏观任务和微观任务(先执行微观任务,再执行宏观任务):
在事件循环中,每进行一次循环操作称为tick,tick 的任务处理模型是比较复杂的,里边有两个词:分别是 Macro Task (宏任务)和 Micro Task(微任务)。
简单来说:
宏观任务主要包含:setTimeout、setInterval、script(整体代码)、I/O、UI 交互事件、setImmediate(Node.js 环境)
微观任务主要包括:Promise、MutaionObserver、process.nextTick(Node.js 环境)
规范:先执行微观任务,再执行宏观任务
那么我们知道了,Promise 属于微观任务, setTimeout、setInterval 属于宏观任务,先执行微观任务,等微观任务执行完,再执行宏观任务。所以我们再看一下这个代码:
console.log('开始111'); setTimeout(function() { console.log('setTimeout111'); }, 0); Promise.resolve().then(function() { console.log('promise111'); }).then(function() { console.log('promise222'); }); console.log('开始222');
我们按照步骤来分析下:
1、遇到同步任务,直接先打印 “开始111”。
2、遇到异步 setTimeout ,先放到队列中等待执行。
3、遇到了 Promise ,放到等待队列中。
4、遇到同步任务,直接打印 “开始222”。
5、同步执行完,返回执行队列中的代码,从上往下执行,发现有宏观任务 setTimeout 和微观任务 Promise ,那么先执行微观任务,再执行宏观任务。
所以打印的顺序为: 开始111 、开始222 、 promise111 、 promise222 、 setTimeout111 。
同理,我们再来分析一个代码:
console.log('开始111'); setTimeout(function () { console.log('timeout111'); }); new Promise(resolve => { console.log('promise111'); resolve(); setTimeout(() => console.log('timeout222')); }).then(function () { console.log('promise222') }) console.log('开始222');
分析一下:
1、遇到同步代码,先打印 “开始111” 。
2、遇到setTimeout异步,放入队列,等待执行 。
3、中途遇到Promise函数,函数中再resolve执行前属于同步,所以直接执行,打印 “promise111”。
4、遇到resolve成功返回 setTimeout ,属于异步,放入队列,等待执行。
5、遇到then成功的异步,放入队列。
6、遇到同步,打印 “开始222”。
7、执行完,返回,将异步队列中的代码,按顺序执行。有一个微观任务,then后的,所以打印 “promise222”,再执行两个宏观任务 “timeout111” “timeout222”。
所以,打印de顺序为:开始111 、 promise111 、 开始222 、 promise222 、 timeout111 、 timeout222 .
这就是循环机制。
先执行主任务,把异步任务放入循环队列当中,等待主任务执行完,再执行队列中的异步任务。异步任务先执行微观任务,再执行宏观任务。一直这样循环,反复执行,就是时间循环。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Python学习教程:从Excel到Python最常用的32个Pandas函数(一)
本次的Python学习教程涉及pandas最常用的36个函数,通过这些函数介绍如何完成数据生成和导入、数据清洗、预处理,以及最常见的数据分类,数据筛选,分类汇总,透视等最常见的操作。 生成数据表 常见的生成数据表的方法有两种,第一种是导入外部数据,第二种是直接写入数据。Excel中的“文件”菜单中提供了获取外部数据的功能,支持数据库和文本文件和页面的多种数据源导入。 Python支持从多种类型的数据导入。在开始使用Python进行数据导入前需要先导入pandas库,为了方便起见,我们也同时导入numpy库. import numpy as npimport pandas as pd导入外部数据 df=pd.DataFrame(pd.read_csv('name.csv',header=1))df=pd.DataFrame(pd.read_Excel('name.xlsx'))c里面有很多可选参数设置,例如列名称、索引列、数据格式等 直接写入数据 df = pd.DataFrame({"id":[1001,1002,1003,1004,1005,1006],"date":pd.date_...
- 下一篇
Elasitcsearch中国开发者报告调研 | 获奖名单公布
2012年 Elasticsearch 首个版本发布,经过6年多的更新迭代,Elastic Stack 生态已经日渐成熟,Elastic 软件在国内拥有越来越多的用户,应用Elasticsearch的开发人群也不断扩大。 为了深入了解 Elasticsearch 开发者群体的现状,2019年11月,Elastic社区、阿里云Elasticsearch技术团队和阿里云开发者社区三方联合发起了Elasticsearch开发者研活动。 在调研过程中,1186位开发者完成了调研问卷,18位技术专家完成了专题访问。参与调研的开发者们从不同角度,分享了个人特征、社会属性、技术能力、从业经历等信息;在Elasticsearch技术的应用、行业实践、职业发展等方面,真实的提供了反馈。 作为首次国内发起的针对 Elasticsearch 开发者群体的行业
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Hadoop3单机部署,实现最简伪集群