js【深度解析】代码的执行顺序

news2025/6/17 2:13:16

代码的分类

我们将每一句要执行的 js 代码当做一个任务,则 js 代码可以按照其执行方式的不同,按下图分类

在这里插入图片描述

  • 同步任务:立即执行的代码
  • 异步任务:延迟执行的代码
    • 微任务:被放入微任务队列(micro task queue)中等待执行的代码

      因为Promise、async 、await 都是 ES6 语法定义的

    • 宏任务:被放入 Web APIs 中等待执行的代码

      因为 setTimeout 、setInterval、ajax、Dom事件都是浏览器定义的

不同类型代码执行的顺序和过程

1. 同步任务

  1. 将其放入调用栈(Call Stack)中
  2. 执行该段代码
  3. 将其从调用栈中移除

除 Promise、async 、await、setTimeout 、setIntervall、ajax、Dom事件之外的代码都是可立即执行的同步任务

2. 微任务

  1. 将其放入微任务队列中等待执行

  2. 待所有同步任务执行完毕,开始按微任务队列依次执行微任务

    将第1个进入微任务队列的微任务放入调用栈中,执行微任务内的代码,将其从调用栈中移除,再将第2个进入微任务队列的微任务放入调用栈中,执行,移除…… 以此类推,直到清空微任务队列。

3. DOM 渲染

微任务队列清空后,便暂停 js 代码的执行,开始尝试渲染 DOM, 若没有 DOM操作,则跳过此步。

因 JS 可修改 DOM 结构 , 所以 js 代码的执行和 DOM 渲染必须共用一个线程,这便导致 js 代码的执行和 DOM 渲染无法同时进行。

4. Event Loop 事件轮询

DOM渲染完毕后,便触发Event Loop,开始事件轮询

5. 宏任务

  1. 将其放入 Web APIs 中,并开始计时

  2. 计时结束后,将其放入回调队列(Callback Queue)

  3. 回调队列中的宏任务,依次被事件轮询到

    将第1个进入回调队列的宏任务放入调用栈中,执行宏任务内的代码,将其从调用栈中移除,再将第2个进入回调队列的宏任务放入调用栈中,执行,移除…… 依此类推,直到清空回调队列。

最终 js 代码的执行顺序

因不同类型的代码可能层层嵌套,所以最终 js 代码的执行顺序可能非常复杂,但总的运行方式,如上文所言,根据代码的不同,将其放入不同的队列或栈中,然后依次执行,核心要领在于

  1. 依次执行可执行的同步任务,直到清空调用栈
  2. 依次执行微任务队列中的微任务,直到清空微任务队列
  3. 暂停 js 代码的执行,尝试渲染DOM,若无DOM操作,则直接进入第4步,若有DOM操作,则待DOM渲染完成,进入第4步
  4. 开始事件轮询,依次执行回调队列中的宏任务(事件轮询会一直进行下去,一旦有新的宏任务计时结束进入回调队列,就会被送去调用栈执行)

简单概括如下图所示:

在这里插入图片描述

自测题

console.log(100)

// 宏任务
setTimeout(() => {
    console.log(200)
})

// 微任务
Promise.resolve().then(() => {
    console.log(300)
})

console.log(400)

答案 100 400 300 200

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");

答案

script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

解析:详见代码注释

// 定义函数,先跳过
async function async1() {
  console.log("async1 start"); // 2
  await async2(); // 先执行 async2() , 进入 async2 函数内

  // await 后的代码都是微任务,将其放入微任务队列 --- 微任务 1
  console.log("async1 end"); // 6
}

// 定义函数,先跳过
async function async2() {
  console.log("async2"); // 3
}

// 同步任务
console.log("script start"); // 1

// 宏任务 1
setTimeout(function () {
  console.log("setTimeout"); // 8
}, 0);

// 同步任务
async1(); // 进入 async1 函数内

// 同步任务 -- Promise 函数体内的代码会立刻执行
new Promise(function (resolve) {
  console.log("promise1"); // 4
  resolve(); // Promise 状态变为 resolved , 立即触发了 then 函数
}).then(function () {
  // then 函数是个微任务,将其放入微任务队列 --- 微任务 2
  console.log("promise2"); // 7
});

// 同步任务
console.log("script end"); // 5

// 同步任务执行完毕,开始执行微任务
// 依次执行微任务1 和 微任务 2
// 最后执行宏任务

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

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

相关文章

AI给开发经验3-5年的程序员的一些建议

Q: 你是一名CTO,请你给开发经验3-5年的程序员一些职业和生活方面的建议,1500字。 A: 作为一名有着丰富经验的CTO,我深知程序员在职业道路上的成长并非一帆风顺。针对开发经验在3-5年的程序员,我想从职业和生活两个方面&#xff0…

【NR 定位】3GPP NR Positioning 5G定位标准解读(十一)-增强的小区ID定位

前言 3GPP NR Positioning 5G定位标准:3GPP TS 38.305 V18 3GPP 标准网址:Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读(一)-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读(…

idm对比aria2哪个好 aria2和idm哪个快 Aria2和IDM的原理

一、idm对比aria2哪个好 下面对aria2和idm进行对比,看看哪款更好。 idm: 优势: 1)可将下载速度提升5倍以上; 2)界面友好,操作简便; 3)支持多个主流的浏览器; 4&am…

linux 查看打开使用了哪些端口

你可以使用 netstat 命令来查看Linux系统中正在使用的端口。例如,要查看所有正在使用的TCP和UDP端口,你可以运行: sudo netstat -tulpn如果你只想查看所有正在使用的TCP端口,你可以运行: sudo netstat -tpln 如果你只…

通过Step Back提示增强LLM的推理能力

原文地址:enhancing-llms-reasoning-with-step-back-prompting 论文地址:https://arxiv.org/pdf/2310.06117.pdf 2023 年 11 月 6 日 Introduction 在大型语言模型不断发展的领域中,一个持续的挑战是它们处理复杂任务的能力,这…

ES入门七:索引管理Api的使用

索引设置 在传家索引的时候,可以在“settings”字段中指定索引的位置。numbers_of_shards和nubmer_of_replicas 是索引非常重要的两个配置,设置它们值的示例如下: 我们还可以动态修改索引的位置,其示例如下:如上示例…

接收端编程、UDP编程练习、wireshrak抓包工具、UDP包头

我要成为嵌入式高手之3月6日Linux高编第十六天&#xff01;&#xff01; ———————————————————————————— 学习笔记 接收端 recvfrom #include <sys/types.h> #include <sys/socket.h> ssize_t recvfrom(int sockfd, void *buf, si…

AI绘画提示词案例(宠物

目录 1. 雪地猫猫&#xff1a;1.1 提示词&#xff1a;1.2 效果&#xff1a; 2. 趴地猫猫&#xff1a;2.1 提示词&#xff1a;2.2 效果&#xff1a; 3. 长城萨摩耶&#xff1a;3.1 提示词&#xff1a;3.2 效果&#xff1a; 4. 沙发猫猫&#xff1a;4.1 提示词&#xff1a;4.2 效…

2024年新手视频剪辑软件推荐-6款视频剪辑软件测评

视频剪辑软件推荐 premiere premiere 直达地址:各大软件网站 说到底,还是得专业的来,虽然很多人觉得他是收费的,但是你懂的,想要免费总是会有办法的.别的不说,剪辑这块,我还是很认可这个软件,虽然我现在还是刚入门. 剪映 剪映 抖音官方推出的一款手机视频编辑剪辑应用,提供切割…

opencv编程

opencv编程 引言&#xff1a; ​ 本实验旨在介绍使用OpenCV进行图像处理和视频处理的基本操作。OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源计算机视觉库&#xff0c;提供了丰富的图像和视频处理功能&#xff0c;既可以进行图像的读取、显示…

猫头虎分享已解决Bug || 批处理错误:BatchJobFailure, ProcessingDelay

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

手机号验证码重新发送

前文叙述 很久以前做的一个 demo &#xff0c;纯 HTML 、CSS、js 制作&#xff0c;一定时间段之后才可以重新发送验证码&#xff0c;如 60s 后再次发送验证码&#xff0c;在该时间段内发送验证码按钮为禁用状态&#xff0c;实战开发过程也亦是同理&#xff0c;因此记录一手。 一…

【IEEE列表会议】IEEE第三届信息与通信工程国际会议国际会议(JCICE 2024)

会议简介 Brief Introduction 2024年第三届信息与通信工程国际会议国际会议 (JCICE 2024) 会议时间&#xff1a;2024年5月10日-12日 召开地点&#xff1a;中国福州 大会官网&#xff1a;JCICE 2024-2024 International Joint Conference on Information and Communication Engi…

王道机试C++第 4 章 字符串:字符串内容续写几个小程序 Day30

统计字符 习题描述 统计一个给定字符串中指定的字符出现的次数。 输入描述&#xff1a; 测试输入包含若干测试用例&#xff0c;每个测试用例包含2行&#xff0c;第1行为一个长度不超过5的字符串&#xff0c;第2行为一个长度不超过80的字符串。注意这里的字符串包含空格&…

Unity性能优化篇(十) 模型优化之网格合并 Easy Mesh Combine Tool插件使用以及代码实现网格合并

把多个模型的网格合并为一个网格。可以使用自己写代码&#xff0c;使用Unity自带的CombineMeshes方法&#xff0c;也可以使用资源商店的插件&#xff0c;在资源商店搜Mesh Combine可以搜索到相关的插件&#xff0c;例如Easy Mesh Combine Tool等插件。 可大幅度减少Batches数量…

零、自然语言处理开篇

目录 0、NLP任务的基础——符号向量化 0.0 词袋模型 0.1 查表/One-hot编码 0.2 词嵌入模型/预训练模型 0.2.0 Word2Vec &#xff08;0&#xff09;CBOW &#xff08;1&#xff09;Skip-gram 0.2.1 GloVe 0.2.2 WordPiece 0.2.3 BERT 0.2.4 ERNIE NLP自然语言处理&am…

微信小程序-入门

1.下载和安装Npm&#xff1a;Npm https://docs.npmjs.com/downloading-and-installing-node-js-and-npm 或者 https://nodejs.org/en/download/ 未安装npm 提示 以下以安装node安装包为例 按任意键继续 安装完成后 2. 下载和安装小程序开发工具 &#xff1a;https:/…

@EnableWebMvc介绍和使用详细demo

EnableWebMvc是什么 EnableWebMvc 是 Spring MVC 中的一个注解&#xff0c;它用于启用 Spring MVC 框架的基本功能&#xff0c;以便你可以使用 Spring MVC 提供的特性来处理 Web 请求。 通常情况下&#xff0c;在基于 Spring Boot 的应用中&#xff0c;并不需要显式地使用 Ena…

音视频开发_音频基础知识

如何采集声音——模数转换原理 声音模数转换是将声音信号从模拟形式转换为数字形式的过程。它是数字声音处理的基础&#xff0c;常用于语音识别、音频编码等应用中。 音视频通信流程 音视频采集&#xff1a;首先是从麦克风、摄像头等设备中采集音频和视频数据&#xff0c;将现…

免费下载Corel Video Studio 2024-轻松创建令人惊叹的视频!

免费下载Corel Video Studio 2024-轻松创建令人惊叹的视频&#xff01; Corel Video Studio 2024免费下载Keygen 你厌倦了在视频编辑软件上花大钱吗&#xff1f;别再看了&#xff01;我们为您提供了完美的解决方案——Corel Video Studio 2024。最棒的部分是什么&#xff1f;…