事件循环机制

初认识:

javaScript事件循环进制是一个用于处理异步事件的回调函数的机制。是JavaScript实现异步编程的核心。

  1. 用于管理任务队列和调用栈,以及在适当的时候执行回调函数。
  2. 可以监听消息队列中的事件,并根据事件处理的优先级顺序来依次执行相应的回调函数。

事件循环机制允许JavaScript在等待某些任务(异步任务:通常需要一定时间才能完成)完成的同时,可以执行其他任务,避免了阻塞,解决了单线程并发性的问题。

JavaScript事件循环是为了解决JavaScript的单线程并发性问题,实现单线程非阻塞。javaScript是一个单线程,同一时间只能执行一件事情。这样单一的特性会导致JavaScript在处理长时间运行的操作的时候出现阻塞,阻塞主要还是异步任务的问题。

基础:

  • 同步任务:只有前一个任务执行完成之后,才能执行后一个任务。Promise()的参数,在async函数中的await右边的代码都是作为同步代码执行的
  • 异步任务:在执行这个任务的同时,可以执行别的任务,异步任务都是耗时的。不进入主线程,进入“任务队列"的任务,当主线程的任务运行完了之后,才会从“任务队列”取出,放入主线程执行。

微任务(microtask):

  • promise,只有Promise.then()的回调函数才会放入微任务中
  • async (async函数中的await右边的代码是同步代码)
  • await
  • process.nextTick(node)
  • mutationObserve

宏任务(macrotask):

  • script
  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI render

执行顺序(优先级):同步任务 -> 微任务 -> 宏任务。不断重复这个过程。(JS引擎指向代码是从上往下执行)

宏任务中的微任务执行顺序:宏任务执行完之后,微任务就一个接一个的执行。

在一轮循环中,会先执行一个宏任务,然后把微任务队列中的所有任务全部执行。然后在下一轮循环中,继续这样执行。

事件循环:

参考信息:并发模型与事件循环 - JavaScript | MDN (mozilla.org)

可视化展示:

事件循环组成:

参考资料:事件循环机制-执行栈、调用栈 - 渣渣逆天 - 博客园 (cnblogs.com)

一看就懂的事件循环机制(event loop) - 掘金 (juejin.cn)

调用栈(Stack):

调用栈用于存储在代码执行阶段创建的所有执行上下文。

js有且只有一个调用栈,因为js在某个时刻只能做一件事。

调用栈的目的是为了帮助 JS编译器 用于追踪函数被调用的顺序的一种机制。

演示:

const second = () => {
  console.log('Hello there!')
}
const first = () => {
  console.log('Hi there!')
  second();
  console.log('The End')
}
first()

堆(heap):

保存的地址。

对象被分配在堆中,堆是一个用来表示一大块(通常是非结构化的)内存区域的计算机术语。

队列(Queue):

保存事件对应的回调函数,在事件执行时,被弹出。

一个 JavaScript 运行时包含了一个待处理消息的消息队列。每一个消息都关联着一个用以处理这个消息的回调函数。

在 事件循环 期间的某个时刻,会从最先进入队列的消息开始处理队列中的消息。被处理的消息会被移出队列,并作为输入参数来调用与之关联的函数。正如前面所提到的,调用一个函数总是会为其创造一个新的栈帧。

函数的处理会一直进行到栈再次为空为止;然后事件循环将会处理队列中的下一个消息(如果还有的话)。

Web API:

浏览器提供了多种异步的Web API,如DOM,times(计时器),AJAX等。

当我们调用一个 Web API 时,如 setTimeout,setTimeout函数会被 push 调用栈顶然后执行,但是 setTimeout 的回调函数不会立即被 push 到调用栈顶,而是起一个计时器任务。当这个计时器结束时,该回调函数会被塞到任务队列(CallBack Queue)中。这个队列中的回调函数的调用就是由事件循环机制来控制的。

理解: 调用任务时,并不会马上进入任务队列,而是先调用web提供的api,等待执行的结果才放进去任务队列

事件循环效果展示视频:一个动画搞清前端js事件循环,面试再也不慌了_哔哩哔哩_bilibili

 

举栗子🌰:

参考视频:面试官:说一说事件循环?_哔哩哔哩_bilibili

栗子1:

console.log('script start');
async function async1(){// 微任务
    await async2();// 同步任务
    console.log('async1 end');
}
async function async2(){// 同步任务
    console.log('async2 end');
}
async1()
setTimeout(function(){// 宏任务
    console.log('setTimeout1');// 同步任务
    new Promise(res => res())
    .then(()=>{
        console.log('promise in timer1');
    })
    .then(()=>{
        console.log('promise in timer2');
    })
},0)
setTimeout(function(){// 宏任务
    console.log('setTimeout2');
},0)
new Promise(resolve => {// 微任务
    console.log('promise1');// 同步任务
    resolve()
    console.log('promise2');
})
    .then(function(){
        console.log('promise3');
    })
    .then(function(){
        console.log('promise4');
    })
console.log('script end');
// 结果
script start
async2 end
promise1  
promise2  
script end
async1 end
promise3  
promise4  
setTimeout1
promise in timer1
promise in timer2
setTimeout2

栗子2:

new Promise(resolve=>{
    console.log('promise1');
    resolve()
    console.log('promise2');
})
    .then(function(){
        console.log('promise3');
        setTimeout(function(){
            console.log('setTimeout3');
        },0)
    })
    .then(function(){
        console.log('promise4');
        setTimeout(function(){
            console.log('setTimeout4');
        },0)
    })
    .then(function(){
        console.log('promise5');
        setTimeout(function(){
            console.log('setTimeout5');
        },0)
    })
// 结果
promise1
promise2
promise3
promise4
promise5
setTimeout3
setTimeout4
setTimeout5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/339392.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

渐开线齿轮计算软件开发Python

从0开始开发计算软件,欢迎大家加入 源代码仓库

深入剖析:Kafka流数据处理引擎的核心面试问题解析75问(5.7万字参考答案)

Kafka 是一款开源的分布式流处理平台,被广泛应用于构建实时数据管道、日志聚合、事件驱动的架构等场景。本文将深入探究 Kafka 的基本原理、特点以及其在实际应用中的价值和作用。 Kafka 的基本原理是建立在发布-订阅模式之上的。生产者将消息发布到主题&#xff08…

三天吃透Java集合面试八股文

内容摘自我的学习网站:topjavaer.cn 常见的集合有哪些? Java集合类主要由两个接口Collection和Map派生出来的,Collection有三个子接口:List、Set、Queue。 Java集合框架图如下: List代表了有序可重复集合&#xff0c…

Unity 抽象工厂模式(实例详解)

文章目录 简介实例1实例2 简介 抽象工厂模式是一种创建型设计模式,它提供了一种方式来封装一组相关或相互依赖对象的创建过程,而无需指定具体类。这种模式常用于系统中有多组相关产品族,且客户端需要使用不同产品族中的对象时。 在Unity中&a…

高效减少组织自发荧光,提高信噪比

在免疫组化检测过程中,许多样本组织会产生可通过各种波长滤光片的组织内源性自发荧光,干扰抗体标记的目的蛋白荧光的观察,甚至导致实验失败。为了解决免疫组化实验中的自发荧光,VectorLabs公司(国内代理商欣博盛生物&a…

【OCR项目】之用HALCON的深度学习工具进行文字识别,并导出到C++调用

前言 HALCON是一个强大的机器视觉工具,包含了2D,3D图像各种算子,以及各种任务的深度学习工具,包括目标检测,实例分割,文字识别等。 这次从实际生产的角度,来分享一下如何用HALCON进行文字识别…

python for循环的基础及面试题

当前版本: Python 3.8.4 简介 for 循环是一种重复执行特定代码块的控制流结构。它可以遍历序列(例如列表、元组、字符串)或其他可迭代对象(例如字典、集合)中的元素。每次迭代循环时,会将元素赋值给一个变…

scipy通过快速傅里叶变换实现滤波

文章目录 fft模块简介fft函数示例滤波 fft模块简介 scipy官网宣称,fftpack模块将不再更新,或许不久之后将被废弃,也就是说fft将是唯一的傅里叶变换模块。 Fourier变换极其逆变换在数学上的定义如下 F ( ω ) ∫ − ∞ ∞ f ( t ) e − i ω…

C++中的static(静态)

2014年1月19日 内容整理自The Cherno:C系列 2014年1月20日 内容整理自《程序设计教程:用C语言编程 第三版》 陈家骏 郑滔 -----------------------------------------------------------------------------------------------------------------------------…

猛玛LARK M1无线麦克风采用 思远半导体 其实就是蓝牙话筒

自上世纪无线电技术开始发展起来,到了几十年后的今天,无线通讯技术已经成熟,开始追求更好的音质以及用户使用体验,优秀的产品也如雨后春笋般的出现,技术革新,极致音质,竞争也越来越激烈。这时候…

LMDeploy 大模型量化部署实践

文章目录 核心功能量化推理引擎推理服务 量化原理补充 部署: 在设备上运行起来,能够接受输入,返回输出。 最重要的就是性能和效率方面的考虑。大模型也是模型的一种,内存开销大,7b 要14G左右的显存。 因为是自回归的方…

Linux:使用for+find查找文件并cp到其他目录,文件名带有空格

一、场景描述 在终端窗口中,用shell命令,批量拷贝文件到指定目录。 我是在Windows系统上,通过git bash终端来执行shell命令的。 二、实现过程 命令1 for filepath in find /d/LearningMaterials/数学/数学/高中/一数/偏基础(基…

MySQL的下载、安装、配置、登录,配置(图+文)(超级详细)

一、 软件的下载 1. 下载地址 官网: https://www.mysql.com 2. 打开官网,点击 DOWNLOADS 然后,点击 MySQL Community(GPL) Downloads 3. 点击 MySQL Community Server 4. 在 General Availability(GA) Releases 中选择适合的版本 …

基于SpringBoot的智慧社区居家养老健康管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

【Unity小技巧】3D人物移动脚步和跳跃下落音效控制

文章目录 单脚步声多脚步声,跳跃落地音效播放不同材质的多脚步声完结 单脚步声 public AudioClip walkingSound; public AudioClip runningSound;//移动音效 public void MoveSound() {// 如果在地面上并且移动长度大于0.9if (isGround && moveDirection.s…

上位机图像处理和嵌入式模块部署(qt图像处理)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 很多人一想到图像处理,本能的第一反应就是opencv,这也没有错。但是呢,这里面还是有一个问题的,不知…

利用Anaconda安装pytorch和paddle深度学习环境+pycharm安装后不能调用pytorch和paddlepaddle框架

问题现象: 之前安装后不能在添加pytorch和paddlepaddle框架 原因(疑似): 在终端中显示pytorch和paddle在C盘但是安装是安装在J盘 解决办法: 卸载、删除文件重新安装后可以看到文件位置在J盘中 但是选择时还是显示C…

JavaEE中什么是Web容器?

Web容器(也称为Servlet引擎)是一个用于执行Java Servlet和JSP的服务器端环境。它负责管理和执行在其上运行的Web应用程序。 Tomcat是Web容器 Apache Tomcat 是一个流行的开源的Web容器,它实现了Java Servlet和JavaServer Pages(…

Linux中的软件包管理器yum

目录 1.什么是软件包 2.关于 rzsz 3.查看软件包 4.如何安装软件 5.如何卸载软件 1.什么是软件包 ● 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. ● 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理…

《WebKit 技术内幕》之五(3): HTML解释器和DOM 模型

3 DOM的事件机制 基于 WebKit 的浏览器事件处理过程:首先检测事件发生处的元素有无监听者,如果网页的相关节点注册了事件的监听者则浏览器会将事件派发给 WebKit 内核来处理。另外浏览器可能也需要处理这样的事件(浏览器对于有些事件必须响应…