返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JS 中的 Event Loop 是什么你真的懂
  • 723
分享到

JS 中的 Event Loop 是什么你真的懂

2024-04-02 19:04:59 723人浏览 八月长安
摘要

目录setTimeout 定时器并不准宏任务和微任务一道经典异步题结尾Event Loop,简单翻译就是 事件循环,是 js 语言下实现运行时的一个机制。 JS 的异步并不

Event Loop,简单翻译就是 事件循环,是 js 语言下实现运行时的一个机制。

JS 的异步并不像其他语言(比如 Java)的异步那样可以实现真正的并发执行,本身其实是个单线程

JS 是维护了一个 任务队列,每当要执行一些异步任务,比如定时器或者是点击按钮触发的事件响应函数。它们不会立即执行,而是放到这个队列里,等待已经在排队的其他任务先执行完,才轮到它们。

队列是一个操作受限的有序列表,表现为为先进入的元素必须先出去,即 “先进先出”,很像排队的感觉。

不过也有一些特殊的队列,比如优先级队列,它是优先级高的元素先出队。

之所以叫 Event Loop,因为它的逻辑可以描述为下面代码:​

while (queue.waitFORMessage()) {
  queue.processNextMessage();
}

当一个任务被完成后,队列会变成等待下一个任务状态,然后处理下一个任务,如此循环往复。

因为 JS 的代码执行本身是一个单线程,为了不让执行阻塞,JS 会把网络请求操作、渲染浏览器页面等操作,交给其他的线程,等待其他线程处理好把结果返回给 JS。

所以 JS 不合适 CPU 密集型,更适合 io 密集型的场景。因为它只有一个线程,如果计算耗时太长,就会阻塞其他要执行的任务,导致卡顿,甚至崩溃。

setTimeout 定时器并不准

setTimeout 在特定时间后要执行的函数,并不会立即执行,而是会先放到任务队列中,先等待前面的任务同步执行完成了,才能执行我们这个。

下面看一个例子,因为第一个 setTimout 有一个非常耗时的同步任务,导致下一个 setTimeout 的执行阻塞,比前面一个 setTimeout 执行要慢半秒。

const start = new Date().getTime();
setTimeout(() => {
  console.log('1:', new Date().getTime() - start);
  let num = 0;
  for (let i = 0; i < 999999999; i++) {
    num = i;
  }
}, 1000);
setTimeout(() => {
  console.log('2:', new Date().getTime() - start);
}, 1000);

定时器的时间,指的是能执行的最早时间,但不能保证一定能在这个时间点立即执行。

宏任务和微任务

任务队列并不是严格意义上的先进先出的正常队列,是可以调整执行顺序的。

我们将要执行的任务分为宏任务和微任务,其中宏任务是正常的先进先出,而微任务则是可以插队,优先于宏任务先执行。宏任务必须在所有微任务执行后才能执行。

当我们给任务队列添加一个微任务时,它会跑到任务队列宏任务前。多个微任务入队时,会保持它们的相对顺序。

宏任务有:

  • script,即 html 嵌入的脚本。
  • setTimeout / setInterval 定时器。
  • setImmediate,这是 nodejs 特有的 api
  • requestAnimationFrame,会在页面重绘前执行。
  • I/O 操作,比如网络请求完成的回调函数执行任务、还比如点击按钮要执行的回调等。这些操作其实是其他的线程完成后触发的,暂且归纳为 I/O 操作。

微任务有:

  • Promise 从 pending 状态转换为其他状态时,触发 then/catch/finaly 中的函数,比如  Promise.resolve().then(fn) 。这是最常见的微任务。
  • MutationObserver,用于监听 DOM 的变化。
  • process.nextTick,nodejs 特有的 API。

任务队列,理论上一个就够了,但也可以是多个队列的组合,没有强行要求。

多个任务队列的实现可以更好地实现优先级的控制,比如对于定时器任务,理论上应该是在多个宏任务中最先执行比较好。浏览器没考虑这种情况,但 nodejs 给宏任务中也设置优先级,会让定时器任务最先执行。

Event Loop 还是挺复杂的,标准文档也比较长,我也没怎么看,感兴趣可以看看。

https://html.spec.whatwg.org/multipage/WEBappapis.html#event-loops。

一道经典异步题

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  console.log("async2");
}
console.log("script start");
setTimeout(function() {
  console.log("setTimeout");
}, 0);
async1();
new Promise(function(resolve) {
  console.log("promise1");
  resolve();
}).then(function() {
  console.log("promise2");
});
console.log('script end')

解题思路为:

  • 找到同步代码。同步代码有:普通同步代码、new Promise(fn) 执行传入的回调函数、async 执行时遇到 await 的前面部分(包括  await 的右侧函数执行也是同步的,这里是易错点 )。
  • 看看任务队列中有哪些微任务和宏任务,记住微任务全执行完了才会执行宏任务。
  • 执行任务,任务里面的异步任务又按顺序进入到任务队列。

结果是:

// 同步代码
script start
async1 start
async2
promise1
script end
// 微任务
async1 end
promise2
// 宏任务
setTimeout

结尾

JS 运行机制是单线程,当有多个异步任务要同时执行,并不能并发执行,必须让优先级高的任务执行完才能执行后面的。如果正在执行的任务比较耗时,会导致后面的任务被阻塞。

Event Loop 的机制中,最基本的一条就是:微任务比宏任务先执行。

到此这篇关于JS 中的 Event Loop 是什么?的文章就介绍到这了,更多相关JS 中的 Event Loop内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JS 中的 Event Loop 是什么你真的懂

本文链接: https://lsjlt.com/news/152934.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JS 中的 Event Loop 是什么你真的懂
    目录setTimeout 定时器并不准宏任务和微任务一道经典异步题结尾Event Loop,简单翻译就是 事件循环,是 JS 语言下实现运行时的一个机制。 JS 的异步并不...
    99+
    2024-04-02
  • 你真的懂C++中的namespace用法
    namespace中文意思是命名空间或者叫名字空间,传统的C++只有一个全局的namespace,但是由于现在的程序的规模越来越大,程序的分工越来越细,全局作用域变得越来越拥挤,每个...
    99+
    2024-04-02
  • js在浏览器中的event loop事件队列示例详解
    目录前言认识一个栈两个队列执行过程简单例子难一点的例子总结前言 以下内容是js在浏览器中的事件队列执行,与在nodejs中有所区别,请注意。 都说js是单线程的,不过它本身其实不是单...
    99+
    2024-04-02
  • Flume中的Event是什么
    在Flume中,Event是指从一个数据源发送到目的地的数据单元。一个Event包含了数据本身以及相关的元数据,比如时间戳、主机名等...
    99+
    2024-04-02
  • Spring Boot访问静态资源css/js,你真的懂了吗
    目录一、前言二、Spring Boot 访问静态资源的默认目录2.1 classpath 目录下-访问默认文件夹名为 static2.2 ServletContext 根目录下( s...
    99+
    2024-04-02
  • Java中的布隆过滤器你真的懂了吗
    目录什么是布隆过滤器实现的核心思想怎么理解典型应用场景什么是布隆过滤器 布隆过滤器(Bloom Filter)是一种空间效率非常高的随机数据结构,它利用位数组(BitSet)表示一个...
    99+
    2023-05-18
    Java布隆过滤器原理 Java布隆过滤器应用 Java布隆过滤器
  • jquery中event的概念是什么
    这篇文章主要介绍了jquery中event的概念是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇jquery中event的概念是什么文章都会有所收获,下面我们一起来看看吧。...
    99+
    2024-04-02
  • mysql中event的作用是什么
    MySQL中的事件(Event)是一种在数据库内部实现的调度任务工具,用于执行定期性的SQL语句或存储过程。通过创建事件,您可以指定...
    99+
    2024-04-09
    mysql
  • mysql中event的用法是什么
    在MySQL中,Event是一种用于调度在特定时间执行的操作的机制。通过创建Event,可以在数据库中定期执行一些任务,例如数据备份...
    99+
    2024-03-11
    mysql
  • sql中loop的使用方法是什么
    在SQL中并没有类似于其他编程语言中的循环(loop)结构,因为SQL是一种集合导向的语言,更适合处理集合(表)数据。 在SQL中通...
    99+
    2024-04-22
    sql
  • 你真的知道什么是arguments吗
    是的,arguments 是一个特殊的 JavaScript 对象,它包含了函数被调用时传递给函数的所有参数。它类似于一个数组,可以...
    99+
    2023-09-21
    arguments
  • 你是否真的懂得如何在面试中使用PHP文件Shell?
    在如今的互联网时代,PHP作为一种广泛使用的编程语言,已经成为了许多企业招聘中的必备技能之一。而在PHP的应用中,Shell文件的使用也是非常重要的一部分。在面试中,如果你能够熟练地使用PHP文件Shell,将会让你在面试中脱颖而出,成为招...
    99+
    2023-05-30
    文件 shell 面试
  • oracle中loop循环使用的方法是什么
    在Oracle中,可以使用PL/SQL语言编写循环控制结构,其中包括三种主要的循环语句:LOOP、WHILE和FOR。其中,LOOP...
    99+
    2024-04-09
    oracle
  • Java中的封装、继承和多态,你真的都懂了吗
    目录封装继承多态接口一些建议和小结写在最后的话封装 所谓的封装就是把类的属性和方法使用private修饰,不允许类的调用者直接访问,我们定义如下一个类,可以看到所有的成员变量和成员方...
    99+
    2024-04-02
  • js中的MVC是什么
    本篇内容主要讲解“js中的MVC是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“js中的MVC是什么”吧!MVC是什么?MVC是一种架构模式,它将应用抽象为...
    99+
    2024-04-02
  • mysql binlog event格式是什么样的
    mysql binlog event格式是什么样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。首先发起几个事务,生成一个新的...
    99+
    2024-04-02
  • 一文让你彻底弄懂js中undefined和null的区别
    目录前言一、基本概念1、undefined2、null二、简单区别三、表现形式1、typeof2、== 与 ===3、Object.prototype.toString.call4、...
    99+
    2024-04-02
  • 一文带你搞懂JS中六种For循环的使用
    目录一、各个 for 介绍1、for2、for ... in3、for ... of4、for await...of5、forEach6、map二、多个 for 之间区别1、使用场景...
    99+
    2024-04-02
  • html中js指的是什么
    这篇文章将为大家详细讲解有关html中js指的是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 在html中,js全称JavaScript...
    99+
    2024-04-02
  • 一篇文章让你彻底搞懂js中的位置计算
    目录引言scrollElement.scroll()Element.scrollHeight/scrollWidthElement.scrollLeft/scrollTop判断当前元...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作