JavaScript的执行顺序

news/2024/4/20 21:57:43/文章来源:https://blog.csdn.net/m0_53808238/article/details/129147084

前言

在说 JavaScript 的执行顺序之前,我们先回答一下以下几组程序的输出结果

第 1 组

const output = (v) => {console.log(v);
};setTimeout(() => {console.log(1);
}, 0);
output(2);
console.log(3);// 2 3 1

第 2 组

new Promise((resolve) => {console.log(1);resolve();new Promise((resolve) => {console.log(2);resolve();}).then(() => {console.log(3);new Promise((resolve) => {console.log(4);resolve();}).then(() => {console.log(5);new Promise((resolve) => {console.log(6);resolve();}).then(() => {console.log(7);});});});
}).then(() => {console.log(8);new Promise((resolve) => {console.log(9);resolve();}).then(() => {console.log(10);});
});// 1 2 3 4 8 9 5 6 10 7

看完上面两组案例,是不是会产生这样的疑惑,为什么输出的结果是这样的,别着急,下面我们来详细分析

一、简述

我们都知道 JavaScript 是单线程语言,这表明 JavaScript 同时只能执行一个任务,但执行顺序却并不是自上而下的

这一点,通过上面的案例我们就已经知道了,那么执行规律究竟是什么呢?

要分析 JavaScript 的执行规律,就不得不说一下 JavaScript 的任务分类, JavaScript 分为同步任务异步任务

二、同步任务

同步任务:立即执行的任务,解析时遇到同步任务会被主线程立即读取并执行

同步任务:

  1. console.log()
  2. new Promise()
  3. 直接调用 function()

三、异步任务

异步任务:异步执行的任务,解析时遇到异步任务,直接丢到任务队列中,不会立即读取和执行

异步任务又分为宏任务微任务,执行时优先执行微任务,后执行宏任务

微任务

  1. promise.then()
  2. nextTick()

宏任务

  1. setTimeout()
  2. setInterval()

四、分析

JavaScript 在执行任务之前会先自上而下遍历所有任务,在遍历的过程中如果遇到同步任务则直接执行,执行完成后继续往下遍历,如果遇到异步任务,则放入任务队列中(微任务放入微任务队列,宏任务放入宏任务队列),第一遍遍历完成后,从微任务队列中继续遍历,遇到同步任务立即执行,遇到异步任务继续放入任务队列中,不断的重复这个过程,直到所有任务全部执行完毕,这个不断重复遍历执行的过程,就叫做事件循环

  • 第 1 次循环:遍历所有任务,遇到同步任务立即解析并执行,遇到异步任务则放入任务队列中暂不解析
  • 第 2 次循环:从任务队列中微任务开始循环,重复第 1 次的过程
  • 第 n 次循环:所有同步任务、微任务都执行完毕后,开始循环宏任务,同样重复第 1 次的过程

第 1 组程序 - 解析

const output = (v) => {console.log(v);
};// 异步宏任务,放入任务队列,暂不执行
setTimeout(() => {console.log(1);
}, 0);// 同步任务,立即执行
output(2);// 同步任务,立即执行
console.log(3);

第 2 组程序 - 解析

new Promise((resolve) => {console.log(1);resolve();new Promise((resolve) => {console.log(2);resolve();}).then(() => {console.log(3);new Promise((resolve) => {console.log(4);resolve();}).then(() => {console.log(5);new Promise((resolve) => {console.log(6);resolve();}).then(() => {console.log(7);});});});
}).then(() => {console.log(8);new Promise((resolve) => {console.log(9);resolve();}).then(() => {console.log(10);});
});

这个稍微复杂一点,但也很好分析,我们来模拟一下事件循环

第 1 次循环

// 同步任务,立即执行
console.log(1)
// 同步任务,立即执行new Promise((resolve) => {console.log(2);resolve();})
// 异步任务,放入任务队列
.then(() => {console.log(3);new Promise((resolve) => {console.log(4);resolve();}).then(() => {console.log(5);new Promise((resolve) => {console.log(6);resolve();}).then(() => {console.log(7);});});});
// 异步任务,放入任务队列
.then(() => {console.log(8);new Promise((resolve) => {console.log(9);resolve();}).then(() => {console.log(10);});
});

第一次循环输出结果如下

// 1 2

第 2 次循环

// 同步任务,立即执行
console.log(3);
// 同步任务,立即执行
new Promise((resolve) => {console.log(4);resolve();
}
// 异步任务,放入任务队列
.then(() => {console.log(5);new Promise((resolve) => {console.log(6);resolve();}).then(() => {console.log(7);});});
// 同步任务,立即执行
console.log(8);
// 同步任务,立即执行
new Promise((resolve) => {console.log(9);resolve();
})
// 异步任务,放入任务队列
.then(() => {console.log(10);});

第 2 次循环输出结果如下

// 3 4 8 9

第 3 次循环

// 同步任务,立即执行
console.log(5);
// 同步任务,立即执行
console.log(6);
// 异步任务,放入任务队列
.then(() => {console.log(7);});
// 同步任务,立即执行
console.log(10);

第 3 次循环输出结果如下

// 5 6 10

第 4 次循环

// 同步任务,立即执行
console.log(7);

第 4 次循环输出结果如下

// 7

所有任务全部执行完毕,循环结束,最终输出结果如下

// 1 2 3 4 8 9 5 6 10 7

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

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

相关文章

强化学习DQN之俄罗斯方块

强化学习DQN之俄罗斯方块强化学习DQN之俄罗斯方块算法流程文件目录结构模型结构游戏环境训练代码测试代码结果展示强化学习DQN之俄罗斯方块 算法流程 本项目目的是训练一个基于深度强化学习的俄罗斯方块。具体来说,这个代码通过以下步骤实现训练: 首先…

车机开发【Android SystemUI 架构音量控制详解】

SystemUI介绍 SystemUI摘要 在Android系统中SystemUI是以应用的形式运行在Android系统当中,即编译SystemUI模块会生产APK文件,源代码路径在frameworks/base/packages/SystemUI/,安装路径system/priv-app/-SystemUI。 什么是SystemUI 在前…

使用带有 Moveit 的深度相机来避免碰撞

文章目录 什么是深度相机?如何将 Kinect 深度相机添加到您的环境中在 Rviz 中可视化深度相机数据在取放场景中使用深度相机将深度相机与您的 Moveit 设置一起使用有很多优势。机器人可以避免未知环境中的碰撞,甚至可以对周围的变化做出反应。然而,将深度相机连接到您的设置并…

FlinkSQL行级权限解决方案及源码

FlinkSQL的行级权限解决方案及源码,支持面向用户级别的行级数据访问控制,即特定用户只能访问授权过的行,隐藏未授权的行数据。此方案是实时领域Flink的解决方案,类似离线数仓Hive中Ranger Row-level Filter方案。 源码地址: https…

数据分片(mycat)

1. 数据分片概念: 1.1. 分库分表 什么是分库分表: 将存放在一台数据库服务器中的数据,按照特定方式(指的是程序开发的算法)进行拆分,分散存放到多台数据库服务器中,以达到分散单台服务器负载的…

第51篇-某彩网登录参数分析-webpack【2023-02-21】

声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、网站分析一、前言 今天我们看一个webpack的网站 aHR0cHM6Ly8xMGNhaTUwMC5jYy9sb2dpbg==二、网站分析 首先…

网络协议(一)应用层(自定制协议、HTTP协议)

目录 应用层:负责应用程序之间的数据沟通 一、自定制协议(私有协议) 二、HTTP协议 1)、请求行解析:GET /index.html HTTP/1.1 第一部分:请求方法:多种多样,描述不同的请求目的 …

大数据知识图谱项目——基于知识图谱的医疗知识问答系统(详细讲解及源码)

基于知识图谱的医疗知识问答系统 一、项目概述 本项目基于医疗方面知识的问答,通过搭建一个医疗领域知识图谱,并以该知识图谱完成自动问答与分析服务。本项目以neo4j作为存储,基于传统规则的方式完成了知识问答,并最终以关键词执…

Verilog 学习第五节(串口发送部分)

小梅哥串口部分学习part1 串口通信发送原理串口通信发送的Verilog设计与调试串口发送应用之发送数据串口发送应用之采用状态机实现多字节数据发送串口通信发送原理 1:串口通信模块设计的目的是用来发送数据的,因此需要有一个数据输入端口 2:…

Qt中修改界面类的类名时需要注意的几个修改点

有些时候因为一些原因,需要修改Qt中创建的界面类,需要特别注意几个修改点。 比如将test类修改为test2类 修改test.h名称为test2.h文件;修改test.cpp名称为test2.cpp文件;修改test.ui名称为test2.ui文件;修改pro文件中…

多层感知机的区间随机初始化方法

摘要: 训练是构建神经网络模型的一个关键环节,该过程对网络中的参数不断进行微调,优化模型在训练数据集上的损失函数。参数初始化是训练之前的一个重要步骤,决定了训练过程的起点,对模型训练的收敛速度和收敛结果有重要…

Java基础43 异常(Exception)

异常(Exception)Exception1.1 异常的概念1.2 异常体系图(☆)1.3 异常处理分类1.3.1 运行时异常(☆)1.3.2 编译时异常(☆)1.4 异常处理(☆)1.4.1 try-catch异常…

【Git】Git下载安装与使用(一)

目录 1. 前言 1.1 什么是Git 1.2 使用Git能做什么 2. Git概述 2.1 Git简介 2.2 Git下载与安装 3. Git代码托管服务 3.1 常用的Git代码托管服务 3.2 码云代码托管服务 1. 前言 1.1 什么是Git Git是一个分布式版本控制工具,主要用于管理开发过程中的源代码…

Cookies与Session会话技术详解

引言:日常生活中,人和人之间沟通交流,涉及到一个词----会话,软件中一样存在会话,如:网购登录,访问公司OA系统也是不断的会话,软件中如何管理浏览器客户端和服务端之间会话过程中的会话数据呢&am…

盘点四种自动化测试模型实例及优缺点

一,线性测试 1.概念: 通过录制或编写对应应用程序的操作步骤产生的线性脚本。单纯的来模拟用户完整的操作场景。 (操作,重复操作,数据)都混合在一起。 2.优点: 每个脚本相对独立&#xff0…

【java】java sftp传输 ,java smb传输访问共享文件夹 集成springboot

文章目录java的sftp传输sftp注意事项java smb传输smb注意事项tips: 集成springboot与不集成springboot区别不大,springboot中无非是引入一个maven依赖 加一个Component注解 , 默认是单例; 复制代码前 请先认真看注意事项 java的sftp传输 依赖…

网络安全态势感知研究综述

摘要:随着物联网、云计算和数字化的迅速发展,传统网络安全防护技术无法应对复杂的网络威胁。网络安全态势感知能够全面的对网络中各种活动进行辨识、理解和预测。首先分别对态势感知和网络安全态势感知的定义进行了归纳整理,介绍了网络安全态…

从0探索NLP——导航帖

从0探索NLP——导航帖 人工智能是一个定义宽泛、知识组成复杂的领域,而NLP是人工智能领域中的一类任务,他在哪呢?Emmmmm~不能说都有涉猎只能说全都都沾点: 每次想要针对NLP的某一点进行讲解时,不讲那写细枝末节&…

全链路压力测试

压力测试的目标: 探索线上系统流量承载极限,保障线上系统具备抗压能力 复制代码 如何做全链路压力测试: 全链路压力测试:整体步骤 容量洪峰 -》 容量评估 -》 问题发现 -》 容量规划 全链路压力测试:细化过程 整体目…

YOLOv6-3.0-目标检测论文解读

文章目录摘要算法2.1网络设计2.2Anchor辅助训练2.3自蒸馏实验消融实验结论论文: 《YOLOv6 v3.0: A Full-Scale Reloading 》github: https://github.com/meituan/YOLOv6上版本参考 YOLOv6摘要 YOLOv6 v3.0中YOLOv6-N达到37.5AP,1187FPS&…