Nodejs学习沉淀(二)——核心功能模块理解

Nodejs核心功能模块理解

在开始介绍Nodejs中的核心模块之前,我们先对几个我们必须掌握的,也是使用频率非常高的模块做一个总览(注意,由于已经有其它很好的文章详细介绍模块API的使用,因此本文中并不再赘述,而是更着重梳理对于每一个模块的理解和应用场景,并在贴出详细的参考资料,请谨慎食用

1.Buffer——Nodejs用来处理二进制流数据或者与之交互
2.Stream——Nodejs用来缓解CPU运算压力,一边读取一边返回数据
3.events——事件触发器,触发命名事件来调用函数
4.http(Https)——作为服务端使用时,创建一个HTTP服务器,监听HTTP客户端请求并返回响应。作为客户端使用时,发起一个HTTP客户端请求,获取服务端响应。
5.net——提供了异步网络API来创建基于流的TCP或者IPC服务器和客户端
6.process——不是内置模块,而是一个全局对象,用来感知和控制NodeJS自身进程的方方面面
7.fs—— fs 模块是文件操作的封装,它提供了文件读取、写入、更名、删除、遍历目录、链接等 POSIX 文件系统操作,有异步和同步两个版本
8.vm——引用官方网站的原文,vm(Virtual Machine),即使用V8虚拟机上下文来运行和编译代码,特别注明,这不是一个安全的机制,不要用其运行不受信任的 代码。
9.cluster——由于js是单线程的,cluster模块就提供了一系列的API,方便用户充分利用计算机多核性能,启动nodejs集群


一、Buffer

Nodejs中的Buffer(缓存)类是一个类似于数组,默认以十六进制来保存资源在计算机当中的二进制形式,与Stream也就是流的概念密切相关,其主要的作用就是提供操作处理二进制流数据的API

js不能控制数据到达的速度或时间,也不能控制流的速度。它只能决定何时发送数据。如果还没有到时间,Node.js将把它们放在buffer中,即RAM中的一个小位置,直到将它们发送出去进行处理为止。

对于Buffer,我们需要思考的问题如下:
(1)字符从输入到存储到计算机的表现形式和最终用Buffer表现的过程?
在这里插入图片描述
(2)Buffer类的应用场景?

  • I/O操作(读写文件、TCP协议、RPC层)
  • zlib.js
  • 加解密

(3)Buffer与Cache之间的关系?

缓冲(Buffer)是用于处理二进制流数据,将数据缓冲起来,它是临时性的,对于流式数据,会采用缓冲区将数据临时存储起来,等缓冲到一定的大小之后在存入硬盘中。视频播放器就是一个经典的例子,有时你会看到一个缓冲的图标,这意味着此时这一组缓冲区并未填满,当数据到达填满缓冲区并且被处理之后,此时缓冲图标消失,你可以看到一些图像数据。

缓存(Cache)我们可以看作是一个中间层,它可以是永久性的将热点数据进行缓存,使得访问速度更快,例如我们通过 Memory、Redis
等将数据从硬盘或其它第三方接口中请求过来进行缓存,目的就是将数据存于内存的缓存区中,这样对同一个资源进行访问,速度会更快,也是性能优化一个重要的点。

(4)Buffer有哪些相关的npm包?

(5)Buffer的基本操作是什么?

  • 创建、修改Buffer类型
  • Buffer类型与字符之间的相互转化

(6)Buffer的内存分配机制?

二、Stream

核心模块讲解——stream

Stream首先和Buffer类是密不可分的,是基于Buffer的。

之所以用stream ,是因为一次性读取、操作大文件,内存和网络是“吃不消”的,因此要让数据流动起来,一点一点的进行操作,这其实也符合算法中一个很重要的思想 —— 分而治之

在这里插入图片描述
(1)来源

  1. 从控制台输入
  2. http请求中的request
  3. 读取文件

(2)常用的模块类

  • event-stream
  • awesome-nodejs#streams

(3)核心

  • 流的创建
  • 为什么需要使用流?弊端有哪些?
  • 流的应用实例(http请求、文件读写)
  • Stream和Buffer之间的关系
  • stream的类型有哪些?
三、events事件触发器

[源码解读]一文彻底搞懂Events模块
Node events(事件触发器)(EventEmitter 类)

该模块使用的就是观察者模式,其核心功能在于事件的绑定和触发,使用频率高。
参考一位大佬写的简易观察者模式。

let officeAccounts ={
    // 初始化定义一个存储类型对象
    subscribes:{
        'any':[]
    },
    // 添加订阅号
    subscribe:function(type='any',fn){
        if(!this.subscribes[type]){
            this.subscribes[type] = [];
        }
        this.subscribes[type].push(fn);//将订阅方法存在数组中
    },
    // 退订
    unSubscribe:function(type='any',fn){
        this.subscribes[type] = 
        this.subscribes[type].filter((item)=>{
            return item!=fn;// 将退订的方法从数组中移除 
        });
    },
    // 发布订阅
    publish:function(type='any',...args){
        this.subscribes[type].forEach(item => {
            item(...args);// 根据不同的类型调用相应的方法
        });
    }

}

链接:https://juejin.im/post/5d69eef7f265da03f12e70a5
来源:掘金

然后是应用

let xiaoming = {
    readArticle:function (info) {
        console.log('小明收到的',info);
    }
};

let xiaogang = {
    readArticle:function (info) {
        console.log('小刚收到的',info);
    }
};

officeAccounts.subscribe('程序员成长指北',xiaoming.readArticle);
officeAccounts.subscribe('程序员成长指北',xiaogang.readArticle);
officeAccounts.subscribe('某公众号',xiaoming.readArticle);

officeAccounts.unSubscribe('某公众号',xiaoming.readArticle);

officeAccounts.publish('程序员成长指北','程序员成长指北的Node文章');
officeAccounts.publish('某公众号','某公众号的文章');


总结归纳一下:
(1)应用场景
所有触发了事件触发器的实例,都会拥有一个eventEmitter.on()函数,用来绑定监听事件

  • net.Server 会在每次有新连接时触发事件
  • fs.ReadStream 会在打开文件时触发事件
  • stream会在数据可读时触发事件

(2)核心

  • on
  • emit
  • addListener
  • removeListener
  • 同步还是异步,该如何触发?(process.nextTick、setImmediate)
  • newListener
  • setMaxListeners(n)和defaultMaxListeners之间的区别

感谢阅读,欢迎批评指正,希望大家能够在追求卓越中不断进步,让优秀成为一种习惯~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值