javascript事件循环Event Loop

js Event Loop学习笔记。

1、线程和进程的区别

一个程序至少有一个进程,一个进程至少有一个线程。线程的划分尺度小于进程,使得多线程程序的并发性高。
另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大的提高了程序的运行效率。
线程在执行过程中与进程还是有区别的,每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看,多线程意义在于一个应用程序中,有多个执行部分可以同时执行。但是操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理及资源分配。

2、js为什么是单线程的

JavaScript语言的一大特点就是单线程,也就是说同一时间只能做一件事。这个特性与它的用途有关,作为浏览器脚本语言,js的主要用途是与用户互动以及操作DOM。这决定了它只能是单线程的,否则会带来很多复杂的同步问题。比如,假定js同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除这个节点,这时浏览器应该以哪个线程为准呢?

3、单线程的优劣势

优势:**
1、降低处理复杂性,简化开发。
2、作为用于预处理与用户互动的脚本语言,可以更加容易的处理状态同步的问题。
劣势:
无并发处理能力,任务处于I/O等待状态,导致CPU处理资源的浪费。
于是JavaScript语言将任务分为:同步任务和异步任务。

4、同步

如果在函数返回的时候,调用者就能够得到预期的结果(即拿到预期的返回值或者看到了预期的结果),那么这个函数就是同步的。

Math.sqrt(4);
console.log('Hi');

第一个函数返回时,就拿到了预期的返回值:4的平方根。第二个函数返回时,就看到了预期的效果:在控制台打印字符串Hi。所以这两个函数是同步的。

5、异步

如果在函数返回的时候,调用者还不能够拿到预期的结果,而是需要在将来通过一定的手段得到,那么这个函数就是异步的。

fs.readFile('test.txt', 'utf8', function(err, data) {
    console.log(data);
});

在上面的代码中,我们希望通过fs.readFile函数读取文件test.txt中的内容,并打印出来。但是在fs.readFile函数返回时,我们期望的结果并不会发生,而是要等到文件全部读取完成之后。如果文件很大的话可能要很长时间,所以,fs.readFile函数是异步的。
正是由于JavaScript是单线程的,而异步容易实现非阻塞,所以在JavaScript中对于耗时的操作或者时间不确定的操作,使用异步就成了必然的选择。
从上文可以看出,异步函数实际上很快就调用完成了。但是后面还有执行异步操作、通知主线程、主线程调用回调函数等很多步骤。我们把整个过程叫做异步过程。异步函数的调用在整个异步过程中,只是一小部分
一个异步过程通常是这样的:主线程发起一个异步请求,异步任务接收请求并告知主线程已收到(异步函数返回);主线程可以继续执行后面的代码,同时异步操作开始执行;执行完成后通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)
因此,一个异步过程包括两个要素:注册函数和回调函数,其中注册函数用来发起异步过程,回调函数用来处理结果。

6、任务队列

对于同步任务来说,按顺序执行即可;但是,对于异步任务,各任务执行的时间长短不同,执行完成的时间点也不同,主线程如何调控异步任务呢?这就用到了消息队列
有些文章把消息队列称为任务队列,或者叫事件队列,总之是和异步任务相关的队列
可以确定的是,它是队列这种先入先出的数据结构,和排队是类似的,哪个异步操作完成的早,就排在前面。不论异步操作何时开始执行,只要异步操作执行完成,就可以到消息队列中排队
这样**,主线程在空闲的时候,就可以从消息队列中获取消息并执行**
消息队列中放的消息具体是什么东西?消息的具体结构当然跟具体的实现有关。但是为了简单起见,可以认为:消息就是注册异步任务时添加的回调函数。
JS是有两个任务队列的,一个叫做Macrotask Queue(Task Queue),一个叫做Microtask Queue;
**Macrotask Queue(宏任务):**进行比较大型的工作,常见的有setTimeout,setInterval,用户交互操作,UI渲染等;
**Microtask Queue(微任务):**进行较小的工作,常见的有Promise、new MutaionObserver()、Process.nextTick;
任务队列中的微任务先执行,然后执行宏任务。

7、事件循环 Event Loop

JavaScript调控同步和异步的机制叫做事件循环。
在这里插入图片描述
事件循环大致分为以下几个步骤:
(1)所有同步任务都在主线程上执行,形成一个执行栈。
(2)主线程之外,还存在一个"任务队列"。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
例子,看下面程序的输出结果:

 console.log('start');//同步任务
 const interval = setInterval(() => {//异步任务,进入任务队列,宏任务
       console.log('setInterval');
   }, 0);
   setTimeout(() => {/异步任务,进入任务队列,宏任务
       console.log('setTimeout 1');
       Promise.resolve()
           .then(() => {
               console.log('promise1');
           }).then(() => {
               setTimeout(() => {
                   console.log('setTimeout 2');
                   clearInterval(interval);
               }, 0);
           })
   }, 0);
   Promise.resolve()
       .then(() => {/异步任务,进入任务队列,微任务
           console.log('promise2');
       });

结果:
在这里插入图片描述

在使用Python来安装geopandas包时,由于geopandas依赖于几个其他的Python库(如GDAL, Fiona, Pyproj, Shapely等),因此安装过程可能需要一些额外的步骤。以下是一个基本的安装指南,适用于大多数用户: 使用pip安装 确保Python和pip已安装: 首先,确保你的计算机上已安装了Python和pip。pip是Python的包管理工具,用于安装和管理Python包。 安装依赖库: 由于geopandas依赖于GDAL, Fiona, Pyproj, Shapely等库,你可能需要先安装这些库。通常,你可以通过pip直接安装这些库,但有时候可能需要从其他源下载预编译的二进制包(wheel文件),特别是GDAL和Fiona,因为它们可能包含一些系统级的依赖。 bash pip install GDAL Fiona Pyproj Shapely 注意:在某些系统上,直接使用pip安装GDAL和Fiona可能会遇到问题,因为它们需要编译一些C/C++代码。如果遇到问题,你可以考虑使用conda(一个Python包、依赖和环境管理器)来安装这些库,或者从Unofficial Windows Binaries for Python Extension Packages这样的网站下载预编译的wheel文件。 安装geopandas: 在安装了所有依赖库之后,你可以使用pip来安装geopandas。 bash pip install geopandas 使用conda安装 如果你正在使用conda作为你的Python包管理器,那么安装geopandas和它的依赖可能会更简单一些。 创建一个新的conda环境(可选,但推荐): bash conda create -n geoenv python=3.x anaconda conda activate geoenv 其中3.x是你希望使用的Python版本。 安装geopandas: 使用conda-forge频道来安装geopandas,因为它提供了许多地理空间相关的包。 bash conda install -c conda-forge geopandas 这条命令会自动安装geopandas及其所有依赖。 注意事项 如果你在安装过程中遇到任何问题,比如编译错误或依赖问题,请检查你的Python版本和pip/conda的版本是否是最新的,或者尝试在不同的环境中安装。 某些库(如GDAL)可能需要额外的系统级依赖,如地理空间库(如PROJ和GEOS)。这些依赖可能需要单独安装,具体取决于你的操作系统。 如果你在Windows上遇到问题,并且pip安装失败,尝试从Unofficial Windows Binaries for Python Extension Packages网站下载相应的wheel文件,并使用pip进行安装。 脚本示例 虽然你的问题主要是关于如何安装geopandas,但如果你想要一个Python脚本来重命名文件夹下的文件,在原始名字前面加上字符串"geopandas",以下是一个简单的示例: python import os # 指定文件夹路径 folder_path = 'path/to/your/folder' # 遍历文件夹中的文件 for filename in os.listdir(folder_path): # 构造原始文件路径 old_file_path = os.path.join(folder_path, filename) # 构造新文件名 new_filename = 'geopandas_' + filename # 构造新文件路径 new_file_path = os.path.join(folder_path, new_filename) # 重命名文件 os.rename(old_file_path, new_file_path) print(f'Renamed "{filename}" to "{new_filename}"') 请确保将'path/to/your/folder'替换为你想要重命名文件的实际文件夹路径。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值