事件循环机制(Event Loop)是全面了解javascript代码执行顺序绕不开的一个重要知识点。虽然许多人知道这个知识点非常重要,但是其实很少有人能够真正理解它。特别是在ES6正式支持Promise之后,对于新标准中事件循环的理解就变得更加重要了。这里我们不具体讲Event Loop(有很多文章说得已经足够好了),我们只是做个牵引——为什么需要Event loop和简单介绍。

在知道事件循环机制之前,我们得确信自己掌握了:

  • 执行上下文(Execution context)
  • 函数调用栈(call stack)
  • 队列数据结构(queue)

希望你抛开已有javascript运行机制方面的相关知识,只要知道以上3点知识就好了。

先来看两个简单的例子,看看是否能够得出正确的执行结果。

//demo01
setTimeout(function() {console.log(1);
},0);
console.log(2);for(var i = 0; i < 5; i++) {console.log(3);
}console.log(4);
//demo02
console.log(1);for(let i = 0; i< 5; i++){setTimeout(function() {console.log(i)},Math.floor(Math.random()*10+1)*100)}console.log(3)

(我们假设我们只知道以上3个知识点)很多人在运行之后可能会感到困惑,为什么即使设置了setTimeout的延迟时间为0,代码还是最后执行?再者定时器的时间(随机设定)优于遇到setTimeout的顺序,时间短的就为什么先执行?

同常情况下,决定代码执行顺序的是函数调用栈(call stack),很显然这里的setTimeout中的执行顺序已经不是用call stack能够解释清除的了,这是为什么呢?

答案是队列(queue)。

javascript的一个特点就是单线程,但是很多时候我们仍然需要在不同的时间去执行不同的任务,例如给元素添加点击事件,设置一个定时器,或者发起Ajax请求。因此需要一个异步机制

来达到这样的目的,事件循环机制也因此而来。

那么问题来了浏览器是如何做到Event Loop这个机制的了?这就需要您自行去查找资料或是从分发挥您的想象力。

接下来,就简单介绍一下Event Loop:

每一个JavaScript程序都拥有唯一的事件循环,大多数代码的执行顺序是可以根据函数调用栈的规则执行的,而setTimeout/setInterval或者不同的事件绑定中的代码,则通过队列来执行。

setTimeout为任务源,或者任务分发器,由它们将不同的任务分发到不同的任务队列中去。每一个任务都有对应的任务队列。

任务队列又分为宏任务(macro-task)与微任务(micro-task)两种,在浏览器中(不说node),包括:

  • macro-task:script(整体代码)、setTimeout/setInterval、I/O、UI rendering等。
  • micro-task:Promise。

事件循环的顺序,决定了JavaScript代码的执行顺序。

它从macro-task中的script开始第一次循环。此时全局上下文进入函数调用栈(call stack),直到调用栈清空(只剩下全局上下文,你可以能为这是一个死循环,反正很蠢),在这个过程中,如果遇到任务分发器,就会将任务放入对应队列中去。

第一次循环时,macro-task中其实只有script,因此函数调用栈清空之后,会直接执行所有的micro-task。当所有可执行的微任务执行完毕之后,就表示第一次事件循环已经结束。

第二次循环会再次从macro-task开始执行。此时macro-task中的script队列中已经没有任务了,但是可能会有其它队列任务,而micro-task中暂时还没有任务。此时会先选择其中一个宏任务队列,例如setTimeout,将该队列中的所有任务全部执行完毕,然后再执行此过程中可能产生的微任务。微任务执行完毕之后,再回过头来执行其它宏任务队列中的任务。依次类推,直到所有宏任务队列中的任务都被执行一遍,并且清空了微任务,第二次循环就会结束。

如果在第二次循环过程中,产生了新的宏任务队列,或者之前宏任务队列中的任务暂时没有满足执行条件,例如延迟时间不够后者事件没有触发,那么将会继续同样的顺序重复循环。

原文发布时间为:2018年06月23日
原文作者:Panthon

本文来源: 掘金 如需转载请联系原作者

为什么要有事件循环机制(Event Loop)相关推荐

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

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

  2. 带你了解事件循环机制(Event Loop)

    什么是事件循环机制? 事件循环分为两种,分别是浏览器事件循环和node.js事件循环,本文主要对浏览器事件循环进行描述. 我们都知道JavaScript是一门单线程语言,指主线程只有一个.Event ...

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

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

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

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

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

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

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

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

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

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

  8. 事件循环(Event Loop)

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

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

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

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

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

最新文章

  1. 数据科学工具 Jupyter Notebook 教程(一)
  2. python安装软件 No module named setuptools
  3. python爬虫源码下载 视频_Python爬虫下载视频文件部分源码
  4. Windows Forms DataGridView 中合并单元格
  5. 会员制的cd出租销售java_模式|酒店改造养老会员制盈利模式及交易结构深度探讨...
  6. 【BZOJ 4671】异或图 【斯特林反演】【线性基】【贝尔数复杂度】
  7. php订阅系统,php redis pub/sub(Publish/Subscribe,发布/订阅的信息系统)之基本使用
  8. 【Linux】Linux 标准目录结构
  9. 三层调用关系_你真正的了解MVC三层架构开发模式吗
  10. 化作春泥更护花的上一句是什么?化作春泥更护花作者是谁
  11. qt 获取本地文件夹、文件路径
  12. java 批量爬虫_签名图片一键批量生成 使用Java的Webmagic爬虫实现
  13. 在博客右下角设置透明卡通小美女,附上源码
  14. 使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3
  15. DevOps落地实践:BAT系列:敏捷看板:iCafe vs Tapd
  16. 串口线插入window10,设备管理器无端口选项
  17. 网页底部版权信息如何注明?
  18. mac 系统偏好设置的“安全与隐私”中默认已经去除了允许“任何来源”App的选项
  19. CPIM SRM考试通过
  20. 你想要的宏基因组-微生物组知识全在这(1812)

热门文章

  1. Flutter DecoratedBox装饰容器
  2. Git 本地分支关联远程分支
  3. easyui省市二级联动
  4. c语言下列编程段的错误,C语言编程题目(有错误)
  5. 库、dlopen、函数名都正确,dlsym出错了,怎么回事
  6. ERROR: libass not found using pkg-config2
  7. 错误一例:expected expression before } token
  8. 热烈庆祝排名进入3000!
  9. iOS 监听锁屏/解锁事件
  10. 简述RPL, DPL, CPL的区别与联系