在 事件循环 期间的某个时刻,运行时会从最先进入队列的消息开始处理队列中的消息。被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧。函数的处理会一直进行到执行栈再次为空为止;然后事件循环将会处理队列中的下一个消息(如果还有的话)。

"执行至完成"

每一个消息完整地执行后,其它消息才会被执行。这为程序的分析提供了一些优秀的特性,包括:当一个函数执行时,它不会被抢占,只有在它运行完毕之后才会去运行任何其他的代码,才能修改这个函数操作的数据。这个模型的一个缺点在于当一个消息需要太长时间才能处理完毕时,Web 应用程序就无法处理与用户的交互,例如点击或滚动。为了缓解这个问题,浏览器一般会弹出一个“这个脚本运行时间过长”的对话框。一个良好的习惯是缩短单个消息处理时间,并在可能的情况下将一个消息裁剪成多个消息。

函数 setTimeout 接受两个参数:待加入队列的消息和一个时间值(可选,默认为 0)。这个时间值代表了消息被实际加入到队列的最小延迟时间。如果队列中没有其它消息并且栈为空,在这段延迟时间过去之后,消息会被马上处理。但是,如果有其它消息,setTimeout 消息必须等待其它消息处理完。因此第二个参数仅仅表示最少延迟时间,而非确切的等待时间。

零延迟

零延迟并不意味着回调会立即执行。以 0 为第二参数调用 setTimeout 并不表示在 0 毫秒后就立即调用回调函数。

其等待的时间取决于队列里待处理的消息数量。在下面的例子中,"这是一条消息" 将会在回调获得处理之前输出到控制台,这是因为延迟参数是运行时处理请求所需的最小等待时间,但并不保证是准确的等待时间。

setTimeout 需要等待当前队列中所有的消息都处理完毕之后才能执行,即使已经超出了由第二参数所指定的时间

JS执行顺序

  1. JS是从上到下一行一行执行。
  2. 如果某一行执行报错,则停止执行下面的代码。
  3. 先执行同步代码,再执行异步代码

事件循环的执行过程

  • 同步代码,调用栈执行后直接出栈
  • 异步代码,放到Web API中,等待时机,等合适的时候放入回调队列(callbackQueue),等到调用栈空时eventLoop开始工作,轮询
  • 微任务执行时机比宏任务要早
  • 微任务在DOM渲染前触发,宏任务在DOM渲染后触发
微任务执行时机比宏任务早,微任务由ES6语法规定,宏任务是由浏览器规定

宏任务(Macro tasks)主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)、Ajax、DOM事件

微任务(Microtasks)主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)、async/await

同步任务与异步任务

同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入任务队列。主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。

栈stack:函数调用形成了一个由若干帧组成的栈
堆heap:对象被分配在堆中,堆是一个用来表示一大块(通常是非结构化的)内存区域的计算机术语。
队列:一个 JavaScript 运行时包含了一个待处理消息的消息队列。每一个消息都关联着一个用以处理这个消息的回调函数

事件循环Event Loop的更多相关文章

  1. 简单了解一下事件循环(Event Loop)

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

  2. JS事件循环(Event Loop)机制

    前言 众所周知,为了与浏览器进行交互,Javascript是一门非阻塞单线程脚本语言. 为何单线程? 因为如果在DOM操作中,有两个线程一个添加节点,一个删除节点,浏览器并不知道以哪个为准,所以只能选 ...

  3. 事件循环 event loop 究竟是什么

    事件循环 event loop 究竟是什么 一些概念 浏览器运行时是多进程,从任务管理器或者活动监视器上可以验证. 打开新标签页和增加一个插件都会增加一个进程,如下图:  浏览器渲染进程是多线程,包 ...

  4. 事件循环Event loop到底是什么

    摘要:本文通过结合官方文档MDN和其他博客深入解析浏览器的事件循环机制,而NodeJS有另一套事件循环机制,不在本文讨论范围中.process.nextTick和setImmediate是NodeJS ...

  5. JavaScript事件循环(Event Loop)机制

    JavaScript 是单线程单并发语言 什么是单线程 主程序只有一个线程,即同一时间片断内其只能执行单个任务. 为什么选择单线程? JavaScript的主要用途是与用户互动,以及操作DOM.这决定 ...

  6. 浏览器与Node的事件循环(Event Loop)有何区别?

    前言 本文我们将会介绍 JS 实现异步的原理,并且了解了在浏览器和 Node 中 Event Loop 其实是不相同的. 一.线程与进程 1. 概念 我们经常说 JS 是单线程执行的,指的是一个进程里 ...

  7. JavaScipt 中的事件循环(event loop),以及微任务 和宏任务的概念

    说事件循环(event loop)之前先要搞清楚几个问题. 1. js为什么是单线程的? 试想一下,如果js不是单线程的,同时有两个方法作用dom,一个删除,一个修改,那么这时候浏览器该听谁的?   ...

  8. JavaScript 事件循环 — event loop

    引言 相信所有学过 JavaScript 都知道它是一门单线程的语言,这也就意味着 JS 无法进行多线程编程,但是 JS 当中却有着无处不在的异步概念 .在初期许多人会把异步理解成类似多线程的编程模式 ...

  9. 一文梳理JavaScript 事件循环(Event Loop)

    事件循环(Event Loop),是每个JS开发者都会接触到的概念,但是刚接触时可能会存在各种疑惑. 众所周知,JS是单线程的,即同一时间只能运行一个任务.一般情况下这不会引发问题,但是如果我们有一个 ...

随机推荐

  1. 10大python加速技巧

    简介 目前非常多的数据竞赛都是提交代码的竞赛,而且加入了时间的限制,这就对于我们python代码的加速非常重要.本篇文章我们介绍在Python中加速代码的一些技巧.可能不是很多,但在一些大的循环或者函 ...

  2. java-servlet过滤器和监听

    1 过滤器 过滤器是什么?servlet规范当中定义的一种特殊的组件,用于拦截容器的调用.注:容器收到请求之后,如果有过滤器,会先调用过滤器,然后在调用servlet. 如何写一个过滤器? 写一个ja ...

  3. Vue3 + Socket.io + Knex + TypeScript 实现可以私聊的聊天室

    前言 下文只在介绍实现的核心代码,没有涉及到具体的实现细节,如果感兴趣可以往下看,在文章最后贴上了仓库地址.项目采用前后端模式,前端使用 Vite + Vue3 + TS:后端使用 Knex + Ex ...

  4. C++ UAC 提权 以一个管理员身份运行程序

    这里是我编译的和一个测试Demo:http://pan.baidu.com/s/1qWNgC6C 大家如果看我下边的不是很清楚,可以下载这个具体工程: 群:103197177 C++进阶讨论:欢迎喜欢 ...

  5. C++ 运行单个实例,防止程序多次启动

    利用内核对象 封装的类,使用运行单个实例,防止多次启动Demo 例子下载地址:http://pan.baidu.com/share/link?shareid=3202369154&uk=303 ...

  6. ABC266.

    D 设 \(f_{t,p}\) 代表在 \(t\) 时间点时人在 \(p\) 点的最大收益,在这一步他可以 \(p\) 增加,不动,\(p\) 减少.于是得出状态转移方程:\(f_{t,p} = \m ...

  7. Elasticsearch-shell脚本实现定时删除指定时间以前索引

    〇.前言 因为elastiflow的数据量还是挺大的,接入了两台交换机的flow数据量已经开始有点大了.所以得写个脚本专门来清理索引 一.如何使用elastic的API 1.手动查询所有索引 在ELK ...

  8. Fast.Framework ORM 于中秋节后 正式开源

    Fast Framework 作者 Mr-zhong 开源项目地址 https://github.com/China-Mr-zhong/Fast.Framework QQ交流群 954866406 欢 ...

  9. Windows 10中蓝牙鼠标连接

    最近遇到了一个问题,Windows 10中的蓝牙鼠标无法连接. 在添加蓝牙鼠标的时候系统提示输入PIN码.通常在蓝牙连接两个系统的时候会需要双方输入PIN码来确认身份,但是鼠标这种设备是没有地方显示P ...

  10. 使用J2EE 登录实例开发

    我们先了解下Servlet的生命周期 Servlet部署在容器里,其生命周期由容器管理. 概括为以下几个阶段: 1)容器加载Servlet类. 当第一次有Web客户请求Servlet服务或当Web服务 ...