一文讲清同步异步,消息队列,宏任务 微任务...

news2024/11/25 3:08:33

单线程多线程

什么是线程进程?

进程:是cpu分配资源的最小单位;(是能拥有资源和独立运行的最小单位)

线程: 是cpu调度的最小单位;(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

比喻:进程就是一个公司,每个公司都有自己的资源可以调度;公司之间是相互独立的;而线程就是公司中的每个员工(你,我,他),多个员工一起合作,完成任务,公司可以有一名员工或多个,员工之间共享公司的空间

比喻:1万块儿砖搬上10楼,整栋楼就是进程。一个电梯运就是单线程,多个电梯一起运就是多线程.

什么是单线程多线程?

单线程:

单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。单线程就是进程里只有一个线程。

多线程:

在单个程序中同时运行多个线程完成不同的工作,称为多线程。

浏览器是多进程的:

放在浏览器中,每打开一个tab页面,其实就是新开了一个进程,在这个进程中,还有ui渲染线程,js引擎线程,http请求线程等。 所以,浏览器是一个多进程的。

JS是单线程的:

JavaScript是单线程的,也就是说,同一个时刻,JavaScript只能执行一个任务,其他任务只能等待。

为什么JS要设计成单线程的?

JavaScript 的设计就是为了处理浏览器网页的交互(DOM操作的处理、UI动画等),决定了它是一门单线程语言。如果有多个线程,它们同时在操作 DOM,那网页将会一团糟。

这主要和js的用途有关,js是作为浏览器的脚本语言,主要是实现用户与浏览器的交互,以及操作dom;这决定了它只能是单线程,否则会带来很复杂的同步问题。 举个例子:如果js被设计了多线程,如果有一个线程要修改一个dom元素,另一个线程要删除这个dom元素,此时浏览器就会一脸茫然,不知所措。所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变

同步异步 宏任务 微任务

为什么任务要分为同步任务和异步任务?

那如果一个任务的处理耗时(或者是等待)很久的话,如:网络请求、定时器、等待鼠标点击等,后面的任务也就会被阻塞,也就是说会阻塞所有的用户交互(按钮、滚动条等),会带来极不友好的体验。

所以,又引入了异步任务。

同步任务:同步任务不需要进行等待可立即看到执行结果,比如console

异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求

异步任务又分为宏任务和微任务

为什么要有微任务宏任务?

有些任务优先级更高,我们js允许它插队优先执行

常见的宏任务和微任务:

// 宏任务:script 定时器 延时器(setTimeout,setInterval) ajax请求 ,dom事件

// 微任务: promise.then promise.catch

事件循环(Event Loop)与消息队列(task queue)

概念_EventLoop事件循环:

EventLoop事件循环的是在浏览器中的一个概念.浏览器中的EventLoop:js是单线程的,一次只能做一件事。js在浏览器这个宿主环境中运行。用户交互,定时器,网络请求等等浏览器中的事件会产生对应的任务,任务多了要在任务队列中排队,浏览器的主线程依次取出

任务来执行,此过程不断重复从而形成一个循环,称为eventloop。

执行顺序:


    // 宏任务 微任务 如何执行的
    //  1. 先执行宏任务
    //  2. 当宏任务执行结束了,在执行所有的微任务(如果没有微任务,就不需要执行)
    //  3. 继续执行下一个宏任务了
同步异步代码如何执行:
先把所有的同步代码添加到任务队列,排在前面,然后把异步代码排到同步代码的后面(注意如果此时,好几个异步代码都有时间,比如过几秒后再执行,那么谁先被放任务队列中,谁的等待时间短就会被先放进去)

宏任务微任务面试题:

<!-- 第一题 -->
<!-- <script>
  console.log(1)
  setTimeout(function () {
    console.log(2)
    new Promise(function (resolve) {
      console.log(3)
      resolve()
    }).then(function () {
      console.log(4)
    })
  })

  new Promise(function (resolve) {
    console.log(5)
    resolve()
  }).then(function () {
    console.log(6)
  })
  setTimeout(function () {
    console.log(7)
    new Promise(function (resolve) {
      console.log(8)
      resolve()
    }).then(function () {
      console.log(9)
    })
  })
  console.log(10)
</script> -->

<!-- 第二题 -->
<!-- <script>
  console.log(1)
  setTimeout(() => {
    console.log(2)
  }, 0)
  console.log(3)
</script>
<script>
  console.log(4)
  setTimeout(() => {
    console.log(5)
  }, 0)
  console.log(6)
</script> -->

<!-- 第三题 -->
<script>
  console.log(1)

  setTimeout(function () {
    console.log(2)
  }, 0)

  const p = new Promise((resolve, reject) => {
    console.log(3)
    resolve(1000) // 标记为成功
    console.log(4)
  })

  p.then((data) => {
    console.log(data)
  })

  console.log(5)
</script>

<!-- 第四题 -->
<script>
  new Promise((resolve, reject) => {
    resolve(1)

    new Promise((resolve, reject) => {
      resolve(2)
    }).then((data) => {
      console.log(data)
    })
  }).then((data) => {
    console.log(data)
  })

  console.log(3)
</script>
<!-- 第五题 -->
<!-- <script>
	console.log(1)
	async function fnOne() {
		console.log(2)
		await fnTwo() // 右结合先执行右侧的代码, 然后等待\
		console.log(3)

		// █
		//await 函数()
		// 其它代码
		// 这里会执行这个函数,然后把这儿的其它代码放到微任务里.详见图
	}
	async function fnTwo() {
		console.log(4)
	}
	fnOne() //调用才执行
	setTimeout(() => {
		console.log(5)
	}, 2000)
	let p = new Promise((resolve, reject) => {
		// new Promise()里的函数体会马上执行所有代码
		console.log(6)
		resolve()
		console.log(7)
	})
	setTimeout(() => {
		console.log(8)
	}, 0)
	p.then(() => {
		console.log(9)
	})
	console.log(10)
</script> -->

<!-- <script>
	console.log(11)
	setTimeout(() => {
		console.log(12)
		let p = new Promise((resolve) => {
			resolve(13)
		})
		p.then((res) => {
			console.log(res)
		})
		console.log(15)
	}, 0)
	console.log(14)
</script> -->

<!-- 第六题字节面试 -->
<script>
	async function async1() {
		console.log('1')
		await async2()
		console.log('2')
	}

	async function async2() {
		console.log('3')
	}

	console.log('4')

	setTimeout(function () {
		console.log('5')
	}, 0)

	async1()

	new Promise(function (resolve) {
		console.log('6')
		resolve()
	}).then(function () {
		console.log('7')
	})

	console.log('8')
</script>

注意 :

1.script最先放到宏任务

2.注意setimeout的时间谁快谁先放入宏任务

3.多个script要一开始就连着排队

\

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

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

相关文章

Kafka第一章:环境搭建

系列文章目录 Kafka第一章&#xff1a;环境搭建 文章目录系列文章目录前言一、环境安装1.前置环境2.软件下载3.上传集群并解压4.编写配置文件5.分发配置文件6.修改参数7.环境变量8.启动服务9.编写启动脚本二、主题命令行操作1.查看topic2.创建 first topic3.查看主题的详情4.修…

录制屏幕为什么没有声音?教您录制声画同步的视频

有时我们只顾着录制电脑的画面&#xff0c;而忽视了录制视频的声音&#xff0c;导致录制的视频文件只有画面没有声音。那您知道录制的视频为什么没有声音吗&#xff1f;怎样才能录制声画同步的录屏文件呢&#xff1f;想要录制带声画同步的视频&#xff0c;首先您得拥有一款支持…

[kubernetes]-k8s通过psp限制nvidia-plugin插件的使用

导语&#xff1a; k8s通过psp限制nvidia-plugin插件的使用。刚开始接触psp 记录一下 后续投入生产测试了再完善。 通过apiserver开启psp 静态pod会自动更新 # PSP(Pod Security Policy) 在默认情况下并不会开启。通过将PodSecurityPolicy关键词添加到 --enbale-admission-plu…

【Cocos新手入门】使用 cocos creator 创建多个场景,并通过代码和事件绑定进行切换场景的方法

本篇文章主要讲解使用 cocos creator 创建多个场景&#xff0c;并通过代码和事件绑定进行切换 作者&#xff1a;任聪聪 日期&#xff1a;2023年1月31日 cocos 引擎版本 2.4.3 场景的创建 步骤一、右击资源管理器下的assets目录&#xff0c;点击新建&#xff0c;献出案件一个sc…

NX二开ufun函数UF_MODL_create_section_surface(样条曲线构建截面特征)

本节主要介绍通过样条曲线及截面OPEN API结构体构建截面特征&#xff0c;函数名 UF_MODL_create_section_surface&#xff0c;效果图如下&#xff1a; 1、函数结构 int UF_MODL_create_section_surface &#xff08; UF_MODL_secsrf_data_p_t section_surface_data&#xff0c…

vue2 数据响应式Object.defineProperty

我们通常可以对进行输入框进行数据的监听&#xff0c;只需要用到了input 事件或 change事件&#xff0c;就可以实时监听到数据的改变&#xff0c;但是如果只是一个单独的数据呢&#xff1f;怎么去做监听&#xff0c;watch吗&#xff1f;&#xff1f;哈哈。 所以 vue响应式就用…

基于微信小程序的懒人美食帮小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.…

graalvm把springboot 3.0应用编译为原生应用

文章目录1、GraalVM Native Support依赖2、编译为原生应用2.1、编译为docker镜像2.2、编译为原生应用文件之前的文章《Graalvm 安装和静态编译&#xff08;https://blog.csdn.net/penngo/article/details/128006244&#xff09;》介绍了graalvm的安装和环境配置&#xff0c;普通…

【Rust】6. 结构体与方法

6.1 结构体的定义和实例化 6.1.1 结构体定义、创建实例 6.1.2 创建实例&#xff1a;字段初始化简写语法 6.1.3 创建实例&#xff1a;结构体更新语法&#xff08;注意&#xff1a;数据的移动特性&#xff01;&#xff09; .. 语法&#xff1a;指定了剩余未显式设置值的字段应有…

通信原理笔记—差分脉冲编码调制

目录 差分脉冲编码调制(DPCM)&#xff1a; 预测编码&#xff1a; 预测编码的基本原理: 信号预测的基本方法: ΔPCM与DPCM的主要区别: 差分脉冲编码调制(DPCM)&#xff1a; 实际信源的特点&#xff1a;实际信源大都是有记忆的信源&#xff1a;信源的相邻输出符号间(如&…

无广告,小体积,实用性拉满的5款软件

人类与99%的动物之间最大差别在于是否会运用工具&#xff0c;借助好的工具&#xff0c;能提升几倍的工作效率。 1. 无损放大图片——Bigjpg 大杀器&#xff01;深度卷积神经网络实现噪点和锯齿部分补充&#xff0c;从而达到图片无损放大。图片边缘也不会有毛刺和重影,。更重要…

(深度学习快速入门)第四章第二节:什么是卷积神经网络

文章目录一&#xff1a;为什么DNN不适合图像处理&#xff08;1&#xff09;图像的空间信息被丢失&#xff08;不具备空间不变性&#xff09;&#xff08;2&#xff09;参数爆炸二&#xff1a;什么是卷积神经网络三&#xff1a;CNN应用一&#xff1a;为什么DNN不适合图像处理 &…

【关于PostgreSQL的系统信息函数的OID】

一、自带的OID的相关脚本 在PostgreSQL的安装包的src/include/catalog目录下&#xff0c;有着两个脚本&#xff0c;unused_oids和 duplicate_oids。通过这两个可执行脚本&#xff0c;可以查看当前源码包配置里的符合要求的OID。unused_oids可以查看若根据当前源码包初始化产生…

YOLOv5训练结果性能分析

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 可参照以下博客一起看&#xff08;涉及一些概念解析&#xff09;深度学习之常用模型评估指标&#xff08;一&#xff09;—— 分类…

Python大数据处理利器,PySpark的入门实战

PySpark极速入门 一&#xff1a;Pyspark简介与安装 什么是Pyspark&#xff1f; PySpark是Spark的Python语言接口&#xff0c;通过它&#xff0c;可以使用Python API编写Spark应用程序&#xff0c;目前支持绝大多数Spark功能。目前Spark官方在其支持的所有语言中&#xff0c;…

OpenCV-Python学习(18)—— OpenCV 图像几何变换之图像平移(cv.warpAffine)

1. 学习目标 学习图像的平移矩阵&#xff1b;学习 OpenCV 图像平移函数。 2. 图像的平移矩阵 平移是物体位置在水平和垂直方向的移动。 像素点 (x,y) 沿 x 轴平移 dx、沿 y 轴平移 dy&#xff0c;公式&#xff1a; 3. 图像平移函数 3.1 cv.warpAffine() 函数使用 cv.war…

R语言生物群落(生态)数据统计分析与绘图

包含&#xff1a;《R语言基础》、《tidyverse数据清洗》、《多元统计分析》、《随机森林模型》、《回归及混合效应模型》、《结构方程模型》、《统计结果作图》七合一版本 R 语言作的开源、自由、免费等特点使其广泛应用于生物群落数据统计分析。生物群落数据多样而复杂&#…

手动启动Oracle服务和Oracle监听服务和init.ora文件相关

Oracle 11g 安装未完全成功&#xff1b;安装完以后&#xff0c;服务只有2个&#xff1b;这样是用不了&#xff0c;oracle服务和oracle监听服务都没有&#xff1b; 尝试启动一下数据库&#xff0c;出现12560错误&#xff1b; 根据资料&#xff0c;可用如下命令启动Oracle服务&am…

【06】FreeRTOS临界段代码保护及调度器挂起与恢复

目录 1.临界段代码保护简介 2.临界段代码保护函数介绍 2.1任务级临界区调用格式示例 2.2中断级临界区调用格式示例 2.3函数调用特点 2.4任务级进入和退出临界段函数 2.5中断级进入和退出临界段函数 3.任务调度器的挂起和恢复 3.1任务调度器挂起函数vTaskSuspendAll() …

为什么大部分虚拟主机都配置SSD

对于任何站长来说&#xff0c;拥有一个不会加载的漂亮网站可能是毁灭性的。选择正确的托管服务对于确保网站始终以最佳状态运行至关重要。而由于新手站长呈爆发性增长态势&#xff0c;选择虚拟主机的站长日趋增多。本文就将介绍大部分虚拟主机都配置SSD的原因。SSD优势SSD在数据…