事件循环的原理是什么

简介: 事件循环是一种编程机制,用于在单线程环境中处理多个任务。它通过维护一个任务队列,按顺序执行每个任务,并在任务之间切换,从而实现并发处理。在每个循环中,事件循环检查是否有新的任务加入队列,并执行就绪的任务。
  1. 基本概念
    • 事件循环是一种机制,用于协调和处理异步任务以及同步任务之间的执行顺序。在JavaScript环境(包括浏览器和Node.js)中,它是处理单线程中各种任务的核心。因为JavaScript是单线程语言,这意味着它一次只能执行一个任务,所以需要一种机制来管理任务的执行顺序,事件循环就是这样的机制。
  2. 任务队列与执行栈
    • 执行栈(Call Stack)
      • 执行栈是一个用于存储函数调用的栈结构。当一个函数被调用时,它就会被压入执行栈的顶部,函数执行完成后,它就会从栈顶弹出。这个栈遵循后进先出(LIFO)的原则。例如,在以下代码中:
        function a() {
                 
        console.log('a');
        }
        function b() {
                 
        a();
        }
        b();
        
        AI 代码解读
      • 首先b函数被调用,b函数被压入执行栈。在b函数内部调用a函数,此时a函数被压入执行栈。当a函数执行完毕(打印a)后,a函数从执行栈弹出,然后b函数执行完毕也从执行栈弹出。
    • 任务队列(Task Queue)
      • 任务队列用于存储异步任务的回调函数。当一个异步操作(如setTimeoutPromise等)完成时,它的回调函数会被放入任务队列。任务队列分为宏任务队列(Macro - task Queue)和微任务队列(Micro - task Queue)。
      • 宏任务包括script(整体代码)、setTimeoutsetIntervalI/O操作、postMessageMessageChannel等。例如,setTimeout函数会在指定的时间后将回调函数放入宏任务队列。
      • 微任务包括Promise.thenMutationObserver等。微任务的优先级高于宏任务。当执行栈为空时,事件循环会先检查微任务队列,如果有微任务,就会将微任务依次放入执行栈执行,直到微任务队列为空。
  3. 事件循环的运行过程
    • 当JavaScript代码开始执行时,首先会将全局代码(script)作为一个宏任务压入执行栈。在执行全局代码的过程中,可能会产生异步操作。
    • 例如,当遇到setTimeout函数时,浏览器或Node.js会启动一个定时器,当定时器时间到达后,setTimeout的回调函数会被放入宏任务队列。而当遇到Promise对象的then方法时,then方法中的回调函数会被放入微任务队列。
    • 当执行栈为空时,事件循环会首先检查微任务队列。如果微任务队列中有任务,就会将微任务队列中的任务依次放入执行栈执行。
    • 当微任务队列清空后,事件循环会检查宏任务队列,将宏任务队列中的第一个任务放入执行栈执行。当这个宏任务执行完毕后,执行栈再次为空,事件循环会再次检查微任务队列和宏任务队列,如此循环往复,直到所有任务都执行完毕。
    • 以以下代码为例:
      console.log('start');
      setTimeout(() => {
             
        console.log('setTimeout');
      }, 0);
      Promise.resolve().then(() => {
             
        console.log('Promise.then');
      });
      console.log('end');
      
      AI 代码解读
    • 首先,console.log('start')console.log('end')作为全局代码(宏任务)的一部分被执行。然后,setTimeout的回调函数被放入宏任务队列,Promise.resolve().then的回调函数被放入微任务队列。当全局代码执行完毕后,执行栈为空,此时事件循环检查微任务队列,发现Promise.then的回调函数,将其放入执行栈执行,打印Promise.then。然后微任务队列清空,事件循环检查宏任务队列,将setTimeout的回调函数放入执行栈执行,打印setTimeout
目录
打赏
0
3
3
0
211
分享
相关文章
搭建 PostgreSQL 流复制主从指南(适用于 CentOS 7.x)
搭建 PostgreSQL 流复制主从指南(适用于 CentOS 7.x)
359 7
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
4574 5
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
Appscan手工探索、手工测试功能实战
Appscan手工探索、手工测试功能实战
JAVA获取重定向地址URL的两种方法
【10月更文挑战第17天】本文介绍了两种在Java中获取HTTP响应头中的Location字段的方法:一种是使用HttpURLConnection,另一种是使用Spring的RestTemplate。通过设置连接超时和禁用自动重定向,确保请求按预期执行。此外,还提供了一个自定义的`NoRedirectSimpleClientHttpRequestFactory`类,用于禁用RestTemplate的自动重定向功能。
446 0
|
11月前
|
在Linux中,如何配置软件RAID?
在Linux中,如何配置软件RAID?
Dockerfile中的CMD和ENTRYPOINT
**Dockerfile 中的 `CMD` 和 `ENTRYPOINT` 用于设定容器启动行为。`CMD` 提供默认命令,可被 `docker run` 覆盖;`ENTRYPOINT` 设置不可变的入口点,其参数与 `CMD` 结合使用。两者皆有两种语法格式:数组和字符串。`ENTRYPOINT` 与 `CMD` 结合允许用户覆盖默认参数,但若需替换 `ENTRYPOINT`,需使用 `--entrypoint`。**
354 0
8-20|https://gitlab.xx.com/api/v4/projects/4/trigger/pipeline Request failed状态码400
根据具体情况,逐步检查这些因素,找到引发400状态码的原因,并进行相应的修复。
223 0
Kubernetes(K8s 1.27.x) 快速上手+实践,无废话纯享版
Kubernetes(K8s 1.27.x) 快速上手+实践,无废话纯享版
536 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问