js 彻底搞懂事件循环机制 Event Loop
我们都知道javascript是单线程语言,就是因为单线程的特性,就不得不提js中的同步和异步
一、同步和异步
所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就是同步任务,比如简单的逻辑操作及函数,而异步任务不会立马立马执行,会挪步放到到异步队列中,比如ajax、promise、事件、计时器等等。
也就是先执行同步,主线程结束后再按照异步的顺序再次执行。
二、时间循环(Event Loop)
Event Loop是什么?中文翻译是事件循环,等待主线程中任务全部完成后,再回来把异步队列中任务放到主程序中运行,这样反复的循环,就是事件循环。

先来看组代码
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函数,函数直接执行,打印 “promise111”。
4、遇到setTimeout ,属于异步,放入队列,等待执行。
5、遇到Promise的then等待成功返回,异步,放入队列。
6、遇到同步,打印 “开始222”。
7、执行完,返回,将异步队列中的代码,按顺序执行。有一个微观任务,then后的,所以打印 “promise222”,再执行两个宏观任务 “timeout111” “timeout222”。
所以,打印的顺序为:开始111 、 promise111 、 开始222 、 promise222 、 timeout111 、 timeout222 .
先执行主任务,把异步任务放入循环队列当中,等待主任务执行完,再执行队列中的异步任务。异步任务先执行微观任务,再执行宏观任务。一直这样循环,反复执行,就是事件循环机制。
js 彻底搞懂事件循环机制 Event Loop的更多相关文章
- 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)
JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...
- js事件循环机制(Event Loop)
javascript从诞生之日起就是一门 单线程的 非阻塞的 脚本语言,单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务,非阻塞靠的就是 event lo ...
- js高级-浏览器事件循环机制Event Loop
JavaScript 是队列的形式一个个执行的 同一时间只能执行一段代码,单线程的 (队列的数据结构) 浏览器是多线程的 JavaScript执行线程负责执行js代码 UI线程负责UI展示的 Jav ...
- 初探nodejs事件循环机制event loop
nodejs的特点 nodejs 具有事件驱动和非阻塞I/O的特点. 事件驱动是指nodejs把每一个任务当成事件来处理. 非阻塞I/O是指nodejs遇到I/O任务时,会从线程池调度单独的线程处理I ...
- 关于事件循环机制event loop
setTimeout(()=> { console.log('settimeout') },100) console.log('开始') console.log('结束') new Promis ...
- js--事件循环机制
前言 我们知道JavaScript 是单线程的编程语言,只能同一时间内做一件事,按顺序来处理事件,但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这又是为什么呢?本文来总结一下js 的事件 ...
- Node.js 事件循环(Event Loop)介绍
Node.js 事件循环(Event Loop)介绍 JavaScript是一种单线程运行但又绝不会阻塞的语言,其实现非阻塞的关键是“事件循环”和“回调机制”.Node.js在JavaScript的基 ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- 深入理解JavaScript的事件循环(Event Loop)
一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为 因为它经常被用于类似如下的方式来实现 while (queue.waitForMessage()) ...
随机推荐
- VMware虚拟机 - 解决 Vmware 启动虚拟机报:该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏的问题
问题背景 当虚拟机仍然在运行时,直接关闭电脑,下次重开电脑并想重新启动虚拟机时报了下图问题 解决方案 进入虚拟机所在目录,把 .lck 后缀的文件都删完 Vmware 重新启动虚拟机 成功!!
- 在Linux深度系统deepin下安装docker
wget -qO- https://get.docker.com/ | sh wget -qO- https://get.docker.com/ | sh
- python像matlab类似的符号函数绘图
matplotlib 绘图之前需要先定义数据范围,python 有一个 sympy 包,类似 matlab 里面的符号函数,可以用来进行二维和三维的图像绘制, from sympy.plotting ...
- HDU100题简要题解(2040~2049)
HDU2040 亲和数 题目链接 Problem Description 古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为: 1+2+4+5+10+11+20+2 ...
- Redis 未授权访问漏洞批量提权
一.getshell前提 ①能有对 /root/.ssh/目录写入的权限 ②目标机开启22端口 二.安装依赖 sudo easy_install redis 三.使用 redis python hac ...
- vue中父子间传值和非父子间传值
vue传值一般分三种方式:父组件向子组件传值.子组件向父子间传值.非父子组件进行传值 一.父组件向子组件传值:父组件引用子组件后,通过数据绑定(v-bind)向子组件传值 父组件: <templ ...
- Hadoop大数据平台搭建之前期配置(2)
环境:CentOS 7.4 (1708 DVD) 工具:VMware.MobaXterm 一. 克隆大数据集群 1. 选中已经进行了基本配置的虚拟机,进行克隆. 2. 此处改为"创建完整克 ...
- 硕思logo设计师注册码去哪里找,文末附链接
硕思logo设计师注册码去哪里找呢?当然是硕思logo设计师官网啦! 最近小编总是会被网友们咨询关于logo设计的问题,其中很多网友并不是专业的设计人员,特别是一些设计公司面对新手设计时,往往会不知所 ...
- 详解CorelDRAW中刻刀工具的具体运用
通过CorelDRAW,我们可以将一个对象拆分为两个对象,使用刻刀工具就可以将对象一分为二,保存为一个由两个或者多个子路径组成的对象,可以指定是否要自动闭合路径,或者是否一直将它们打开. CDR刻刀工 ...
- jmeter简单的压力测试
Jmeter是一个非常好用的压力测试工具. Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好.相比LR来说操作简单方便,关键是免费,基于JAVA开发,所以需 ...