蓝桥杯-网络安全比赛(4)基础学习-JavaScript同步与异步、宏任务(MacroTask)与微任务、事件循环机制(MicroTask)

理解JavaScript的异步编程模型对于编写高效、健壮的Web应用程序至关重要。
在Web开发中,经常需要处理异步操作,如网络请求、定时器、文件读写等。
掌握同步和异步的概念,以及宏任务和微任务的处理顺序,可以帮助开发者更好地管理代码的执行流程,避免常见的并发问题,如竞态条件、死锁等。

同步与异步

同步和异步是描述 代码执行顺序 的概念,
而宏任务和微任务则是 在异步编程中用于管理任务 执行顺序优先级的机制。

同步

同步(Synchronous)意味着代码按照顺序一行一行地执行,每一行代码必须等待上一行代码执行完毕才能继续执行。
在同步代码中,如果有某个操作耗时较长,例如读取大文件或发起网络请求,
那么整个程序将会等待这个操作完成,这可能导致程序的响应性变差,甚至造成阻塞。

例如 假设我们有一个同步函数,用于模拟一个耗时操作::

function synTask() {  console.log('开始同步任务');  // 模拟耗时操作  for (let i = 0; i < 1e9; i++) {  // 空循环,不做任何实际操作  }  console.log('同步任务结束');  
}  console.log('开始执行');  
synTask();  
console.log('继续执行');

输出顺序将会是:

开始执行  
开始同步任务  
同步任务结束  
继续执行

异步

异步(Asynchronous)编程允许我们在等待某个操作完成的同时,继续执行其他代码。
这样,程序不必一直等待耗时操作完成,从而提高了程序的响应性和效率。
在JavaScript中,异步操作通常通过回调函数、Promise、async/await等方式来实现。

例如 使用Promise实现的异步案例:

function asynTask() {  return new Promise((resolve, reject) => {  console.log('开始异步任务');  // 模拟异步操作,例如网络请求或定时器  setTimeout(() => {  console.log('异步任务结束');  resolve('任务完成');  }, 1000);  });  
}  console.log('开始执行');  
asynTask().then(result => {  console.log('处理异步任务结果:', result);  
});  
console.log('继续执行');

输出顺序将会是:

开始执行  
开始异步任务  
继续执行  
异步任务结束  
处理异步任务结果: 任务完成

在这个例子中

  1. asynTask函数返回一个Promise对象。
  2. 我们使用setTimeout来模拟一个异步操作,这个操作将在1秒后完成。
  3. 在异步操作完成之前,JavaScript引擎不会等待它,而是继续执行后面的代码。
  4. 当异步操作完成后,我们通过调用resolve方法来解决Promise,并在.then方法中处理异步操作的结果。

宏任务

宏任务(MacroTask)是由宿主环境(如浏览器或Node.js)发起的,可以理解为每次执行栈执行的代码就是一个宏任务。
宏任务队列中存放着需要执行的宏任务,当主线程空闲时,会从宏任务队列中取出一个任务进行执行。

宏任务涵盖了诸如setTimeout、setInterval、Ajax请求、DOM事件等异步操作。这些操作不会被立即执行,而是被放入宏任务队列中,等待主线程空闲时再执行。
由于宏任务通常具有较低的优先级,因此它们可能会被推迟执行,直到没有其他更高优先级的任务需要处理。

微任务

微任务(MicroTask)则是由JavaScript引擎本身创建和调度的,它们在当前任务执行结束后立即执行。
微任务队列是一个与任务队列相互独立的队列,每个微任务都会添加到微任务队列的尾部,并且会按照顺序处理完队列中的所有任务。

微任务通常包括Promise的回调函数、MutationObserver的回调等。
这些微任务在当前宏任务执行完毕后立即执行,即使还有其他的宏任务在队列中等待。
这种机制使得微任务具有比宏任务更高的优先级。

事件循环

在JavaScript的事件循环中,宏任务和微任务共同决定了异步任务的执行顺序。
当主线程中的同步任务执行完毕,事件循环会开始处理异步任务。
它会优先检查微任务队列是否有任务需要执行,如果没有,再去宏任务队列检查是否有任务执行,如此往复。

基本流程

执行栈:JavaScript引擎有一个执行栈,用于同步地执行代码。每当执行一段同步代码时,它都会被推入执行栈中,执行完毕后则会被弹出。

宏任务队列:异步的宏任务(如setTimeout、setInterval、script整体代码等)会被放入宏任务队列中等待执行。

微任务队列:异步的微任务(如Promise.then、process.nextTick等)则会被放入微任务队列中等待执行。

事件循环:当执行栈为空时,事件循环开始工作。

  1. 它首先查看微任务队列,如果有微任务,就将其出队并执行,直到微任务队列为空。
  2. 然后,事件循环从宏任务队列中取出一个宏任务执行。
    在执行宏任务的过程中,可能会产生新的宏任务或微任务,这些都会被相应地放入对应的队列中。
  3. 每执行完一个宏任务,事件循环都会再次查看微任务队列并执行其中的任务,直到微任务队列再次为空。

这个过程会一直重复,形成事件循环。

案例

例如:

console.log('script start'); // 宏任务  setTimeout(function() {  console.log('setTimeout'); // 宏任务  
}, 0);  Promise.resolve().then(function() {  console.log('promise1'); // 微任务  
}).then(function() {  console.log('promise2'); // 微任务  
});  console.log('script end'); // 宏任务

首先执行宏任务script startscript end,然后执行所有的微任务promise1promise2,最后执行下一个宏任务setTimeout

题目1
下面的代码会按照什么顺序输出?
console.log('1');  
setTimeout(() => {  console.log('2');  Promise.resolve().then(() => {  console.log('3');  });  
}, 0);  Promise.resolve().then(() => {  console.log('4');  
});  console.log('5');

首先执行宏任务输出1和5,然后执行微任务输出4。接着执行setTimeout的宏任务输出2,然后再执行其内部的微任务输出3。

所以输出顺序为:1, 5, 4, 2, 3

题目2
下面的代码会按照什么顺序输出?
Promise.resolve().then(() => {  console.log('1');  setTimeout(() => {  console.log('2');  }, 0);  
});  setTimeout(() => {  console.log('3');  Promise.resolve().then(() => {  console.log('4');  });  
}, 0);  console.log('5');

首先执行宏任务输出5,然后执行微任务输出1。接着执行setTimeout的宏任务输出3,然后再执行其内部的微任务输出4。最后执行另一个setTimeout的宏任务输出2。

所以输出顺序为:5, 1, 3, 4, 2


总结

同步与异步是编程中处理耗时操作的两种方式,异步编程通过非阻塞的方式提高了程序的响应性和效率。
宏任务与微任务则是JavaScript事件循环中的两个关键概念,它们共同协作,确保了异步任务的有序执行。

网络安全领域中的许多工具和平台可能会使用到JavaScript或其相关技术。
因此,对JavaScript的深入理解和熟练掌握可以为参赛者在解决某些与Web安全相关的挑战时提供帮助。

系列文章

蓝桥杯-网络安全比赛(3)基础学习- JavaScript的闭包与this
蓝桥杯-网络安全比赛(2)基础学习-正则表达式匹配
蓝桥杯-网络安全比赛(1)基础学习-使用PHP、PYTHON、JAVA

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

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

相关文章

洛谷B3735题解

题目描述 圣诞树共有 n 层&#xff0c;从上向下数第 1 层有 1 个星星、第 2 层有 2 个星星、以此类推&#xff0c;排列成下图所示的形状。 星星和星星之间用绳子连接。第 1,2,⋯,n−1 层的每个星星都向下一层最近的两个星星连一段绳子&#xff0c;最后一层的相邻星星之间连一段…

【linux】join命令

join命令用于将两个文件中&#xff0c;指定栏位内容相同的行连接起来。 找出两个文件中&#xff0c;指定栏位内容相同的行&#xff0c;并加以合并&#xff0c;再输出到标准输出设备。 命令的参数如下&#xff1a; -a1或者-a2表示先输出合并后相同部分内容&#xff0c;然后再输…

No supported authentication methods available (server sent: publickey)

先说折腾方式&#xff1a;以下修改ssh配置以后旧的ssh连接不要断开&#xff0c;重启ssh服务以后都用新连接去测试&#xff0c;万一有问题的话旧的ssh连接不会断开还可以继续修改配置文件&#xff0c;要不都断了就惨了。 ubuntu server 22&#xff0c;使用秘钥方式可以正常登录…

发明专利申请条件

1、新颖性&#xff1a;是指在申请日以前没有同样的发明或者实用新型在国内外出版物上公开发表过&#xff0c;没有在国内公开使用过或者以其他方式为公众所知&#xff0c;也没有同样的发明或者实用新型由他人向国家专利行政部门提出过申请并且记载在申请日以后公布的专利申请文件…

什么是json?json可以存放哪几种数据类型

JSON指的是JavaScript对象表示法(avaScript Object Notation)&#xff0c;是轻量级的文本数据交换格式&#xff0c;独立于语言: JSON使用JavaScript语法来描述数据对象&#xff0c;但是JSON仍然独立于语言和平台&#xff0c;JSON解析器和JSON库支持许多不同的编程语言&#xff…

Python学习从0到1 day20 第二阶段 面向对象 ③ 继承

循此苦旅&#xff0c;以达天际 —— 24.4.3 一、继承的基础语法 学习目标&#xff1a; ① 理解继承的概念 ② 掌握继承的使用方式 ③ 掌握pass关键字的作用 单继承 语法&#xff1a; class 类名(父类名): 类内容体 继承分为&#xff1a;单继承和多继承 继承表示&#xff1a;将从…

WE博客代码系统

WE博客代码系统 说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于asp.net mvc架构和sql server数据库&#xff0c;并采用EF实体模型开发。 三层架构并采用EF实体模型开发 功能模块&#xff1a; WE博客代码系统 WE博客代码系…

Vue指令之v-model

调了半天没反应&#xff0c;结果是没引用Vue&#xff0c;我是伞兵。 v-model的作用是将视图与数据双向绑定。一般情况下&#xff0c;Vue是数据驱动的&#xff0c;即数据发生改变后网页就会刷新一次&#xff0c;更改对应的网页内容&#xff0c;即数据单向绑定了网页内容。而使用…

每日一题————P5725 【深基4.习8】求三角形

题目&#xff1a; 题目乍一看非常的简单&#xff0c;属于初学者都会的问题——————————但是实际上呢&#xff0c;有一些小小的坑在里面。 就是三角形的打印。 平常我们在写代码的时候&#xff0c;遇到打印三角形的题&#xff0c;一般简简单单两个for循环搞定 #inclu…

【C++第三阶段】模板类模板通用数组实现案例

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 模板怎么使用模板函数模板注意事项普通函数与函数模板的区别普通函数与函数模板调用规则函数模板限制 类模板类模板语法类模板与函数模板区别类模板中成员函数创建时机类模板对象做函…

MySQL日志探索——redo log和bin log的刷盘时机详解

我们先简单了解一下大致的刷盘时机&#xff0c;然后配合两阶段提交和组提交来看 redo log的刷盘时机 MySQL 正常关闭时&#xff1b;当 redo log buffer 中记录的写入量大于 redo log buffer内存空间的一半时&#xff0c;会触发落盘&#xff1b; PS&#xff1a;为什么这里要到…

Google Chrome 常用设置

Google Chrome 常用设置 References 转至网页顶部 快捷键&#xff1a;Home 转至内容设置 chrome://settings/content 清除浏览数据 历史记录 -> 清除浏览数据 关于 Chrome 设置 -> 关于 Chrome chrome://settings/help References [1] Yongqiang Cheng, https:/…

关于ansible的模块 ③

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 接《关于Ansible的模块①》和《关于Ansible的模块②》&#xff0c;继续学习ansible的user模块。 user模块可以增、删、改linux远…

回溯算法|491.递增子序列

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums, int startIndex) {if (path.size() > 1) {result.push_back(path);// 注意这里不要加return&#xff0c;要取树上…

MySQL 索引优化(二)

书接上文&#xff0c;继续使用上次创建的 student 表&#xff0c;表里已经被我们装填了大量数据&#xff0c;接下来做分页查询的索引优化。 分页查询优化 普通的分页查询语句&#xff1a; SELECT * FROM student LIMIT 10000,10;这条语句是从 student 表中取出 10001 行开始…

面向对象进阶5:类和泛型

内部类 在一个类的内部定义的类,内部类可以访问外部类的成员变量和成员方法,包括私有成员,内部类可以分为成员内部类,局部内部类,静态内部类和匿名内部类 public class InnerClass {class InnerC{} }1,成员内部类 定义在类中方法外的类,可以访问外部类的所有成员变量和方法,…

人脸识别seetaface6 windows + cmake + vs编译,踩坑指南

遇到问题冷静分析&#xff0c;没有解决不了的问题&#xff0c;只是需要时间。与君共勉 环境准备 要在windows 上编译c 源码&#xff0c;需要准备如下软件。省去了详细的安装过程。 visual studio 2022 (社区免费版链接)mingw64 下载路径 (安装后&#xff0c;记得添加系统路径…

elementui 实现一个固定位置的Pagination(分页)组件

系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 二、elementui 左侧导航菜单栏与main区域联动 三、elementui 中设置图片的高度并支持PC和手机自适应 四、 elementui 实现一个固定位置的Pagination&#xff08;分页&#xff09;组件 文章目录 系列文章目录…

今客CRM客户管理系统 v17.3

简介&#xff1a; 今客CRM客户管理系统主要是为了帮助企业解决在日常工作中遇到的客户管理等难题而开发&#xff0c;通过今客CRM客户管理系统可以对企业事务中的不同功能进行操作&#xff0c;用户通过自定义字段类型可以达到适合不同企业的需求。在今客客户关系管理系统中管理…

【子集回溯】【树枝+树层去重】Leetcode 491. 非递减子序列

【组合回溯】【树枝树层去重】Leetcode 491. 非递减子序列 解法1 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- 解法1 【树层去重】&#xff1a;如果在同层元素重复(这里无法排序&#xff0c;所以无法使用之前的flag&a…