什么是事件循环机制?

事件循环分为两种,分别是浏览器事件循环node.js事件循环,本文主要对浏览器事件循环进行描述。
我们都知道JavaScript是一门单线程语言,指主线程只有一个。Event Loop事件循环,其实就是JS引擎管理事件执行的一个流程,具体由运行环境确定。目前JS的主要运行环境有两个,浏览器和Node.js。

先了解浏览器的进程和线程:

浏览器是多进程的,浏览器每一个打开一个Tab页面(网页)都代表着创建一个独立的进程(至少需要四个,若页面有插件运行,则五个)。渲染进程(浏览器内核)是多线程的,也是浏览器的重点,因为页面的渲染,JS执行等都在这个进程内进行

  1. GUI渲染线程

    负责渲染浏览器界面,包括解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
    当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。
    注意 : GUI渲染线程与JS引擎线程是互斥的。

  2. JS引擎线程

    也称为JS内核,负责解析处理Javascript脚本,运行代码。(例如V8引擎)。
    JS引擎一直等待并处理任务队列中任务。一个Tab页中无论什么时候都只有一个JS线程在运行JS程序

  3. 定时触发器线程

    setInterval和setTimeout所在线程。通过此线程计时完毕后,添加到事件队列中,等待JS引擎空闲后执行

  4. 事件触发线程

    当一个事件被触发时该线程会把事件添加到事件队列,等待JS引擎的处理
    这些事件可来自JS引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

  5. 异步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)相关推荐

  1. 事件循环机制(event loop)

    目录 前言 一.事件循环概述 二.进程和线程 三.为什么JavaScript是单线程? 四.JavaScript如何解决单线程阻塞问题? 五.JavaScript 运行机制 六.任务队列 task q ...

  2. js 循环 等待异步执行完再执行_JS异步执行机制——事件循环(Event Loop)

    JS异步执行机制--事件循环(Event Loop) 本文首发地址: 前端基础 | JS异步执行机制--事件循环(Event Loop)​www.brandhuang.com 先祭出一段代码,你清楚它 ...

  3. js 异步执行_JS异步执行机制——事件循环(Event Loop)

    JS异步执行机制--事件循环(Event Loop) 本文首发地址: 前端基础 | JS异步执行机制--事件循环(Event Loop)​www.brandhuang.com 先祭出一段代码,你清楚它 ...

  4. 理解浏览器和nodeJs中的事件循环(Event Loop)

    浏览器环境下 js 引擎的事件循环机制 js 引擎每次只能执行一个操作,而通常情况下操作又不止一个,因此这些操作会被依次放入一个队列中,js 引擎会按照队列中的顺序去执行操作,这个队列叫做执行栈. 当 ...

  5. 深入理解JavaScript的事件循环(Event Loop) 一、什么是事件循环

    深入理解JavaScript的事件循环(Event Loop) 一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为因为它经常被用于类似如下的方式来实现 ...

  6. js异步等待完成后再进行下一步操作_彻底搞懂JS事件中的循环机制 Event Loop

    我们都知道JavaScript是单线程语言,就是因为单线程的特性,就不得不提js中的同步和异步 一.同步和异步 所谓单线程,无非就是同步队列和异步队列,js代码是自上向下执行的,在主线程中立即执行的就 ...

  7. 事件循环(Event Loop)

    目录 同步任务 异步任务 异步任务分类 例题 众所周知,JS是单线程的,那么如果出现多个任务,这些任务的执行顺序是怎么样的呢?这就不得不提一下事件循环 同步任务 首先,我们用一个栈来表示主线程 当有多 ...

  8. python 结束循环事件,python asyncio事件循环(Event Loop)及事件循环策略(Event Loop Policy)...

    1.asyncio实现了两种事件循环对象: asyncio.SelectorEventLoop:(默认使用)基于Python3.4中添加的selectors模块,它会根据OS自动选择最优的I/Omul ...

  9. 事件循环(Event Loop)相关概念 及 面试题

    小伙伴们,看面试题前,先来看几个概念吧!!! 宏任务 (macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行). 任务(代码) 宏 ...

最新文章

  1. python学习笔记:easygui的简单示例
  2. 【微信小程序企业级开发教程】快递查询实例
  3. JavaScript框架
  4. linux blender 中文乱码,Blender2.7.8中文显示框框乱码该怎么办?
  5. Maven私服的简单搭建教程(Nexus)
  6. URI、URL和URN的关系
  7. servlet ---- 简单案例
  8. LeetCode 407. Trapping Rain Water II
  9. 在cmd下安装Scrapy怎么解决方案python3
  10. vs2015+opencv+dilb+于仕琪人类识别算法对人脸特征点进行检测
  11. 牛牛倒计时抽签软件1.0发布
  12. 【Linux】制作U-Boot烧写镜像到SD卡的过程(下篇:Makefile文件)
  13. String类型的测量长度
  14. 如何使用 Fiddler Everywhere 抓包手机模拟器上的网络请求
  15. 用pandas合并两个csv表格并保存
  16. web网站访问计数器
  17. java文档注释用什么开头,极其重要
  18. 求助!网站重构需要帮手(前端)
  19. 提到区块链,这一次微软没有再落后
  20. mysql数据库工具Navicat常用快捷键介绍

热门文章

  1. MeterSphere使用数据库循环多个变量
  2. 山科的前辈的总结,好多资料专题和建议
  3. vue新手建议学习路线
  4. nginx重定向方法
  5. 机器学习中的生成式模型VS判别式模型,分类,特点
  6. 正点原子STM32103 战舰V3 开发板的ST LINK(SWD)接线图
  7. 新手站长怎样租用高性能的美国服务器?
  8. Python之Pands数据分析,从0到掌握
  9. python保存为.csv文件
  10. 计算机考试前的心情作文,考试前的心情作文