IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 普歌-事件循环-发布npm-Stream -> 正文阅读

[JavaScript知识库]普歌-事件循环-发布npm-Stream

Node的架构分析

  • 浏览器中的EventLoop是根据HTML5定义的规范实现的,不同的浏览器可能会有不同的实现,而Node中是由libuv实现的
  • 来看一下Node架构图:
    在这里插入图片描述

我们会发现libuv中主要维护了一个EventLoop和worker threads(线程池)
EventLoop负责调用系统的一些其他操作:文件的IO、Network、child-processes等

  • libuv是一个多平台的专注于异步IO的库,它最初是为了Node开发的,但是现在也被使用到Luvit、Julia、pyuv等其他地方

阻塞IO和非阻塞IO

如果我们希望在程序中对一个文件进行操作,那么我们就需要打开这个文件:通过文件描述

JavaScript可以直接对一个文件进行操作吗?
看起来是可以的,但是事实上我们任何程序中的文件操作都是需要进行系统调用(操作系统的文件系统)
事实上对文件的操作,是一个操作系统的系统调用(IO系统,IO是输入、输出)

操作系统通常为我们提供了两种调用方式:阻塞时调用非阻塞式调用

阻塞时调用:调用结果返回之前,当前线程处于阻塞态(阻塞态CPU是不会分配时间片的),调用线程只有在得到调用结果之后才会继续执行
非阻塞式调用:调用执行之后,当前线程不会停止执行,只需要过一段时间来检查一下有没有结果返回即可

所以我们开发中的很多耗时操作,都可以基于这样的非阻塞式调用

比如网络请求本身使用了Socket通信,而Socket本身提供了select模型,可以进行非阻塞方式的工作
比如文件读写的IO操作,我们可以使用操作系统提供的基于事件的回调机制

非阻塞IO的问题

但是非阻塞IO也会存在一定的问题:我们并没有获取到需要读取(我们以读取为例)的结果

那么就意味着为了可以知道是否读取到完整的数据,我们需要频繁的去确定读取到的数据是否是完整的
这个过程我们称之为轮训操作

那么这个轮训的工作由谁来完成呢?

如果我们的主线程频繁的去进行轮训的工作,那么必然会大大降低性能
并且开发中我们可能不只是一个文件的读写,可能是多个文件
而且可能是多个功能:网络的IO、数据库的IO、子进程调用

libuv提供了一个线程池(Thread Pool)

线程池会负责所有相关的操作,并且会通过轮训或者其他的方式等待结果
当获取到结果时,就可以将对应的回调放到事件循环(某一个事件队列)中
事件循环就可以负责接管后续的回调工作,告知JavaScript应用程序执行对应的回调函数

在这里插入图片描述

阻塞和非阻塞,同步和异步的区别?

阻塞和非阻塞是对于被调用者来说的

在我们这里就是系统调用,操作系统为我们提供了阻塞调用和非阻塞调用

同步和异步是对于调用者来说的

在我们这里就是自己的程序
如果我们在发起调用之后,不会进行其他任何的操作,只能等待结果,这个过程就称之为同步调用
如果我们在发起调用之后,并不会等待结果,继续完成其他的工作,等到有回调时再去执行,这个过程就是异步调用

Libuv采用的就是非阻塞异步IO的调用方式

Node事件循环的阶段

我们在之前就强调过,事件循环像是一个桥梁,是连接着应用程序的JavaScript和系统调用之间的通道:

无论是我们的文件IO、数据库、网络IO、定时器、子进程,在完成对应的操作后,都会将对应的结果和回调函数放到事件循环(任务队列)中
事件循环会不断的从任务队列中取出对应的事件(回调函数)来执行

但是一次完成的事件循环Tick分成很多个阶段:

定时器(Timers):本阶段执行已经被setTimeout()和setInterVal()的调度回调函数
待定回调(Pending Callback):对某些系统操作(如TCP错误类型)执行回调,比如TCP连接是接收到ECONNREFUSED
idle,prepare:仅系统内部使用
轮训(Poll):检索新的I/O事件;执行与I/O相关的回调
检测:setImmediate()回调函数在这里执行
关闭的回调函数:一些关闭的回调函数,如:socket.on(‘close’,…)

Node循环事件图解

在这里插入图片描述

Node的宏任务和微任务

Node的事件循环更复杂,它也分为微任务和宏任务:

宏任务(macrotask):setTimeout、setInterval、IO事件、setImmediate、close事件
微任务(microtask):Promise的then回调、process.nextTick、queueMicrotask

但是Node中的事件循环不只是微任务队列和宏任务队列:

微任务队列:
next tick queue:process.nextTick
other queue:Promise的then回调、queueMicrotask
宏任务队列:
timer queue:setTimeout、setInterval
poll queue:IO事件
check queue:setImmediate
close queue:close事件

接下里通过题来理解一下 ==>??

在这里插入图片描述

更多推荐《普歌-事件循环


作者:Cnc_zj
本文源自:Cnc_zj的《普歌-事件循环-发布npm-Stream
本文版权归作者和CSDN共有,欢迎转载,且在文章页面明显位置给出原文链接,未经作者同意必须保留此段声明,否则保留追究法律责任的权利。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:33:45  更:2022-04-26 11:36:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:48:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码