JavaScript中的执行顺序

分析下面JavaScript代码的执行顺序:

  <script>setTimeout(() => console.log('代码开始执行'), 0)new Promise((resolve, reject) => {console.log('开始for循环');for (let i = 0; i < 10000; i++) {i == 99 && resolve()}}).then(() => console.log('执行then函数'))console.log('代码执行结束');</script>

控制台输出结果:

分析如下:

        要分析这段JavaScript代码的执行顺序,我们需要理解JavaScript的事件循环和异步行为,特别是setTimeout和Promise的行为。以下是详细的执行顺序分析:

同步代码执行:JavaScript引擎首先会从上到下执行所有同步代码。

        首先,setTimeout(() => console.log('代码开始执行'), 0)被调用。setTimeout是一个异步函数,它会在指定的时间(这里是0毫秒)后将回调函数放入事件队列中。但是,它不会立即执行,而是等待当前执行栈清空后再执行。

        接着,new Promise构造函数被调用,并立即执行它的执行器函数(executor function)。

        在执行器函数内部,console.log('开始for循环')被立即执行,打印出“开始for循环”。

        然后,for循环开始执行,从i = 0迭代到i < 10000。在这个循环中,每次迭代都会检查i == 99,当i等于99时,resolve()函数被调用,这会将.then()中的回调函数放入微任务队列(microtask queue)中,等待当前执行栈清空后执行。

        最后,console.log('代码执行结束')被执行,打印出“代码执行结束”。

微任务执行:当前执行栈清空后,JavaScript引擎会检查微任务队列。

        由于在for循环中当i等于99时调用了resolve(),这导致.then()中的回调函数被添加到微任务队列中。因此,现在微任务队列中有一个回调函数要执行,即console.log('执行then函数')。

        JavaScript引擎执行这个微任务,打印出“执行then函数”。

事件队列中的任务:最后,JavaScript引擎会检查事件队列(event queue)中的任务。

        setTimeout的回调函数被添加到事件队列中(由于延迟时间为0,它几乎是立即被添加的,但还是在所有同步代码和微任务之后执行)。

        当微任务队列为空,且当前执行栈为空时,setTimeout的回调函数被调用,打印出“代码开始执行”。

综上所述,执行顺序如下:

        打印“开始for循环”

        执行for循环(直到i等于99时调用resolve())

        打印“代码执行结束”

        执行.then()中的回调函数,打印“执行then函数”

        最后,执行setTimeout的回调函数,打印“代码开始执行”


Promise构造函数是同步执行的,为什么不是先执行里面的for循环再执行console.log('代码执行结束');?(与Kimi的对话)
        您的问题非常好,这实际上是一个常见的误解。虽然Promise构造函数是同步执行的,但是它里面的异步操作(如setTimeout、setInterval、IO操作等)和同步操作(如循环、条件判断等)的执行顺序,并不是由Promise构造函数的同步性质决定的。

         在JavaScript中,代码的执行顺序是由事件循环(Event Loop)机制决定的。事件循环包括两个重要的队列:宏任务(Macro Task)队列和微任务(Micro Task)队列。宏任务包括:setTimeout、setInterval、IO、UI渲染等;微任务包括:Promise的.then()、.catch()、.finally()、async函数的异步操作等。

        对于您提供的代码,执行顺序如下:

  1. setTimeout函数被调用,将console.log('代码开始执行')放入宏任务队列,等待执行。
  2. new Promise构造函数被同步执行,立即打印'开始for循环'。
  3. 同步执行for循环,这是一个同步操作,会立即执行。
  4. 由于for循环是同步的,它会在Promise构造函数中立即执行完毕,然后Promise构造函数执行结束。
  5. console.log('代码执行结束')是一个同步操作,它会在Promise构造函数执行结束后立即执行。
  6. 此时,主线程的同步代码已经执行完毕,事件循环开始处理宏任务队列和微任务队列。
  7. 由于for循环在i == 99时调用了resolve(),将Promise的状态从pending变为fulfilled,此时注册在.then()中的回调函数console.log('执行then函数')被放入微任务队列。
  8. 事件循环首先处理宏任务队列中的setTimeout回调函数,打印'代码开始执行'。
  9. 然后处理微任务队列中的Promise的.then()回调函数,打印'执行then函数'。

因此,for循环确实是在console.log('代码执行结束')之前执行的,但是Promise的.then()回调函数是在setTimeout回调函数之后执行的,因为微任务队列的优先级高于宏任务队列。

总结来说,Promise构造函数是同步执行的,但是它里面的异步操作和同步操作的执行顺序是由事件循环机制决定的,而不是由Promise构造函数的同步性质决定的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【天壤智能-注册安全分析报告-无验证纯IP限制存在误拦截隐患】

前言 由于网站注册入口容易被机器执行自动化程序攻击&#xff0c;存在如下风险&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露&#xff0c;不符合国家等级保护的要求。短信盗刷带来的拒绝服务风险 &#xff0c;造成用户无法登陆、注册&#xff0c;大量收到垃圾短信的…

SQLAlchemy,ORM的Python标杆!

嗨&#xff0c;Python的小伙伴们&#xff01;今天咱们来了解 SQLAlchemy&#xff0c;这可是对象关系映射&#xff08;ORM&#xff09;里的超级标杆哦&#xff01;它就像一座神奇的桥梁&#xff0c;能让我们用 Python 代码轻松地和数据库打交道&#xff0c;不用写复杂的 SQL 语句…

前端测试工具(Jest与Mock)

Jest 工具详解&#xff1a;从安装到使用** Jest 是一个流行的 JavaScript 测试框架&#xff0c;广泛用于 React 应用及其他 JavaScript 项目的测试。它是由 Facebook 创建的&#xff0c;具有简单、快速、功能强大的特点。 一、Jest 的安装 1.1 环境准备 Jest 需要运行在 Nod…

Makefile 之 wordlist

wordlist $(wordlist <s>,<e>,<text> ) 名称&#xff1a;取单词串函数——wordlist。 功能&#xff1a;从字符串<text>中取从<s>开始到<e>的单词串。<s>和<e>是一个数字。 返回&#xff1a;返回字符串<text>中从…

大数据实验4-HBase

一、实验目的 阐述HBase在Hadoop体系结构中的角色&#xff1b;能够掌握HBase的安装和配置方法熟练使用HBase操作常用的Shell命令&#xff1b; 二、实验要求 学习HBase的安装步骤&#xff0c;并掌握HBase的基本操作命令的使用&#xff1b; 三、实验平台 操作系统&#xff1…

内网安全隧道搭建-ngrok-frp-nps-sapp

1.ngrok 建立内网主机与公网跳板机的连接&#xff1a; 内网主机为客户机&#xff1a; 下载客户端执行 2.frp &#xff08;1&#xff09;以下为内网穿透端口转发 frp服务端配置&#xff1a; bindPort 为frp运行端口 服务端运行 ./frps -c frps.ini frp客户端配置&#xf…

三十一、构建完善微服务——API 网关

一、API 网关基础 系统拆分为微服务后&#xff0c;内部的微服务之间是互联互通的&#xff0c;相互之间的访问都是点对点的。如果外部系统想调用系统的某个功能&#xff0c;也采取点对点的方式&#xff0c;则外部系统会非常“头大”。因为在外部系统看来&#xff0c;它不需要也没…

前端:HTML (学习笔记)【1】

一&#xff0c;网络编程的三大基石 1&#xff0c;URL &#xff08;1&#xff09;url —— 统一资源定位符&#xff1a; 网址——整个互联网中可以唯一且准确的确定一个资源的位置。 【项目外】 网址——https://www.baidu.com/ …

2024-11-21 学习人工智能的Day29 初见深度学习

深度学习前置 Pytorch ​ Pytorch是基于python的深度学习框架&#xff0c;被广泛应用在计算机视觉、自然语言处理、语音识别等领域。PyTorch提供了许多高级功能&#xff0c;如**自动微分&#xff08;automatic differentiation&#xff09;、自动求导&#xff08;automatic g…

实验室管理现代化:Spring Boot技术方案

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

2.langchain中的prompt模板 (FewShotPromptTemplate)

本教程将介绍如何使用 LangChain 库中的 PromptTemplate 和 FewShotPromptTemplate 来构建和运行提示&#xff08;prompt&#xff09;&#xff0c;并通过示例数据展示其应用。 安装依赖 首先&#xff0c;确保你已经安装了 langchain 和相关依赖&#xff1a; pip install lan…

如何在 Microsoft Edge 中设置代理: 快速而简单的方法

你知道在 Microsoft Edge 中设置代理可以大大提升浏览体验吗&#xff1f;无论您是想提高隐私保护、访问受地理位置限制的内容&#xff0c;还是想更高效地浏览网页&#xff0c;代理服务器都能改变一切。 本指南将介绍如何在 Microsoft Edge 中设置代理&#xff0c;解决常见的代…

【机器学习】近似分布的熵到底是p(x)lnq(x)还是q(x)lnq(x)?

【1】通信的定义 信息量&#xff08;Information Content&#xff09;是信息论中的一个核心概念&#xff0c;用于定量描述一个事件发生时所提供的“信息”的多少。它通常用随机变量 &#x1d465;的概率分布来定义。事件 &#x1d465;发生所携带的信息量由公式给出&#xff1…

Excel如何批量导入图片

这篇文章将介绍在Excel中如何根据某列数据&#xff0c;批量的导入与之匹配的图片。 准备工作 如图&#xff0c;我们准备了一张员工信息表以及几张员工的照片 可以看到&#xff0c;照片名称是每个人的名字&#xff0c;与Excel表中的B列&#xff08;姓名&#xff09;对应 的卢易…

【操作系统】操作系统的特征

操作系统的七个基本特征 并发性&#xff08;Concurrence&#xff09; 并发性是指操作系统在同一时间间隔内执行和调度多个程序的能力&#xff0c;提高资源利用率和系统效率。尽管多个任务可能在同一时刻看似同时进行&#xff0c;但实际上&#xff0c;CPU在多个任务之间快速切…

iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录

我们姑且将这款iPhone 17序列的超薄SKU称为“iPhone 17 Air”&#xff0c;Jeff Pu在报告中提到&#xff0c;我同意最近关于 iPhone 17超薄机型采用6 毫米厚度超薄设计的传言。 如果这一测量结果被证明是准确的&#xff0c;那么将有几个值得注意的方面。 首先&#xff0c;iPhone…

springboot嗨玩旅游网站

摘 要 嗨玩旅游网站是一个专为旅行爱好者打造的在线平台。我们提供丰富多样的旅游目的地信息&#xff0c;包括景点信息、旅游线路、商品信息、社区信息、活动推广等&#xff0c;帮助用户轻松规划行程。嗨玩旅游网站致力于为用户提供便捷、实用的旅行服务&#xff0c;让每一次旅…

LLM学习笔记(2)会话补全Chat Completions、什么是JSON?

什么是会话补全Chat Completions&#xff1f; 功能目标&#xff1a;处理多轮对话。 它模拟对话的逻辑&#xff0c;比如聊天机器人对用户消息的回应。使用的模型主要是针对对话型应用优化的模型&#xff0c;例如gpt-3.5-turbo或gpt-4。 什么是JSON&#xff1f; JSON 本质上是…

C++和js对比

1. 变量定义 C&#xff1a; #include <iostream> int main() {// 定义整型变量int num 10;// 定义浮点型变量double pi 3.14159;// 定义字符型变量char ch A;std::cout << "num: " << num << ", pi: " << pi << &…

SpringBoot与MongoDB深度整合及应用案例

SpringBoot与MongoDB深度整合及应用案例 在当今快速发展的软件开发领域&#xff0c;NoSQL数据库因其灵活性和可扩展性而变得越来越流行。MongoDB&#xff0c;作为一款领先的NoSQL数据库&#xff0c;以其文档导向的存储模型和强大的查询能力脱颖而出。本文将为您提供一个全方位…