带你了解事件循环机制(Event Loop)
什么是事件循环机制?
事件循环分为两种,分别是浏览器事件循环和node.js事件循环,本文主要对浏览器事件循环进行描述。
我们都知道JavaScript是一门单线程语言,指主线程只有一个。Event Loop事件循环,其实就是JS引擎管理事件执行的一个流程,具体由运行环境确定。目前JS的主要运行环境有两个,浏览器和Node.js。
先了解浏览器的进程和线程:
浏览器是多进程的,浏览器每一个打开一个Tab页面(网页)都代表着创建一个独立的进程(至少需要四个,若页面有插件运行,则五个)。渲染进程(浏览器内核)是多线程的,也是浏览器的重点,因为页面的渲染,JS执行等都在这个进程内进行
GUI渲染线程
负责渲染浏览器界面,包括解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。
注意 : GUI渲染线程与JS引擎线程是互斥的。JS引擎线程
也称为JS内核,负责解析处理Javascript脚本,运行代码。(例如V8引擎)。
JS引擎一直等待并处理任务队列中任务。一个Tab页中无论什么时候都只有一个JS线程在运行JS程序定时触发器线程
setInterval和setTimeout所在线程。通过此线程计时完毕后,添加到事件队列中,等待JS引擎空闲后执行
事件触发线程
当一个事件被触发时该线程会把事件添加到事件队列,等待JS引擎的处理
这些事件可来自JS引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。异步http请求线程
在XMLHttpRequest连接后是通过浏览器新开一个线程请求。
将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JS引擎执行
Event Loop ( 事件循环 )
浏览器的事件循环分为同步任务和异步任务;所有同步任务都在主线程上执行,形成一个函数调用栈(执行栈),而异步则先放到任务队列(task queue)里,任务队列又分为宏任务(macro-task)与微任务(micro-task)。下面的整个执行过程就是事件循环
宏任务大概包括::script(整块代码)、setTimeout、setInterval、I/O、UI交互事件、setImmediate(node环境)
微任务大概包括::new promise().then(回调)、MutationObserver(html5新特新)、Object.observe(已废弃)、process.nextTick(node环境)
若同时存在promise和nextTick,则先执行nextTick
执行过程
先从script(整块代码)开始第一次循环执行,接着对同步任务进行执行,直到调用栈被清空,然后去执行所有的微任务,当所有微任务执行完毕之后。再次从宏任务开始循环执行,直到执行完毕,然后再执行所有的微任务,就这样一直循环下去。如果在执行微队列任务的过程中,又产生了微任务,那么会加入整个队列的队尾,也会在当前的周期中执行。
下面展示一个简单的参考例子。
setTimeout(function() {console.log('timeout1');
})new Promise(function(resolve) {console.log('promise1');for(var i = 0; i < 1000; i++) {i == 99 && resolve();}console.log('promise2');
}).then(function() {console.log('then1');
})console.log('global1');
首先,事件循环从宏任务队列开始,这时宏任务队列中只有一个script(整体代码)任务。每一个任务的执行顺序,都依靠函数调用栈来完成,而当遇到任务源时,则会先分发任务到对应的队列中去,所以,上面例子的第一步执行如下图所示。
第二步:script任务执行时首先遇到了setTimeout,setTimeout为一个宏任务源,那么他的作用就是将任务分发到它对应的队列中。
第三步:script执行时遇到Promise实例。Promise构造函数中的第一个参数,是在new的时候执行,因此不会进入任何其他的队列,而是直接在当前任务直接执行了,而后续的.then则会被分发到micro-task的Promise队列中去。
因此,构造函数执行时,里面的参数进入函数调用栈执行。for循环不会进入任何队列,因此代码会依次执行,所以这里的promise1和promise2会依次输出。
script任务继续往下执行,最后只有一句输出了globa1,然后,全局任务就执行完毕了。
第四步:第一个宏任务script执行完毕之后,就开始执行所有的可执行的微任务。这个时候,微任务中,只有Promise队列中的一个任务then1,因此直接执行就行了,执行结果输出then1,当然,他的执行,也是进入函数调用栈中执行的。
第五步:当所有的micro-tast执行完毕之后,表示第一轮的循环就结束了。这个时候就得开始第二轮的循环。第二轮循环仍然从宏任务macro-task开始。
这个时候,我们发现宏任务中,只有在setTimeout队列中还要一个timeout1的任务等待执行。因此就直接执行即可。
本文到这里就结束了,但仅这一个例子或许还是不够,可以再找几个例子进一步熟悉下吧
带你了解事件循环机制(Event Loop)相关推荐
- 事件循环机制(event loop)
目录 前言 一.事件循环概述 二.进程和线程 三.为什么JavaScript是单线程? 四.JavaScript如何解决单线程阻塞问题? 五.JavaScript 运行机制 六.任务队列 task q ...
- js 循环 等待异步执行完再执行_JS异步执行机制——事件循环(Event Loop)
JS异步执行机制--事件循环(Event Loop) 本文首发地址: 前端基础 | JS异步执行机制--事件循环(Event Loop)www.brandhuang.com 先祭出一段代码,你清楚它 ...
- js 异步执行_JS异步执行机制——事件循环(Event Loop)
JS异步执行机制--事件循环(Event Loop) 本文首发地址: 前端基础 | JS异步执行机制--事件循环(Event Loop)www.brandhuang.com 先祭出一段代码,你清楚它 ...
- 理解浏览器和nodeJs中的事件循环(Event Loop)
浏览器环境下 js 引擎的事件循环机制 js 引擎每次只能执行一个操作,而通常情况下操作又不止一个,因此这些操作会被依次放入一个队列中,js 引擎会按照队列中的顺序去执行操作,这个队列叫做执行栈. 当 ...
- 深入理解JavaScript的事件循环(Event Loop) 一、什么是事件循环
深入理解JavaScript的事件循环(Event Loop) 一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为因为它经常被用于类似如下的方式来实现 ...
- js异步等待完成后再进行下一步操作_彻底搞懂JS事件中的循环机制 Event Loop
我们都知道JavaScript是单线程语言,就是因为单线程的特性,就不得不提js中的同步和异步 一.同步和异步 所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就 ...
- 事件循环(Event Loop)
目录 同步任务 异步任务 异步任务分类 例题 众所周知,JS是单线程的,那么如果出现多个任务,这些任务的执行顺序是怎么样的呢?这就不得不提一下事件循环 同步任务 首先,我们用一个栈来表示主线程 当有多 ...
- python 结束循环事件,python asyncio事件循环(Event Loop)及事件循环策略(Event Loop Policy)...
1.asyncio实现了两种事件循环对象: asyncio.SelectorEventLoop:(默认使用)基于Python3.4中添加的selectors模块,它会根据OS自动选择最优的I/Omul ...
- 事件循环(Event Loop)相关概念 及 面试题
小伙伴们,看面试题前,先来看几个概念吧!!! 宏任务 (macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行). 任务(代码) 宏 ...
最新文章
- python学习笔记:easygui的简单示例
- 【微信小程序企业级开发教程】快递查询实例
- JavaScript框架
- linux blender 中文乱码,Blender2.7.8中文显示框框乱码该怎么办?
- Maven私服的简单搭建教程(Nexus)
- URI、URL和URN的关系
- servlet ---- 简单案例
- LeetCode 407. Trapping Rain Water II
- 在cmd下安装Scrapy怎么解决方案python3
- vs2015+opencv+dilb+于仕琪人类识别算法对人脸特征点进行检测
- 牛牛倒计时抽签软件1.0发布
- 【Linux】制作U-Boot烧写镜像到SD卡的过程(下篇:Makefile文件)
- String类型的测量长度
- 如何使用 Fiddler Everywhere 抓包手机模拟器上的网络请求
- 用pandas合并两个csv表格并保存
- web网站访问计数器
- java文档注释用什么开头,极其重要
- 求助!网站重构需要帮手(前端)
- 提到区块链,这一次微软没有再落后
- mysql数据库工具Navicat常用快捷键介绍