Nodejs学习笔记【四】

56 阅读3分钟

EventEmitter类

events与EventEmitter

image.png

EventEmitter常见API

image.png

const events = require('events');

const e = new events()
function fn1(){
    console.log('event1');
}
e.on('event1',fn1)
e.on('event1',fn1)
e.emit('event1') // event1 event1-2
e.once('event2',() => {
    console.log('event2');
})
//只调用一次
e.emit('event2') //event2
e.emit('event2') // 不打印
//移除event1事件
e.off('event1',fn1) 

发布订阅模式

定义对象间一对多的依赖关系

发布订阅可以解决什么问题?

订阅者把消息注册在消息调度中心,发布者在需要某消息的时候,去消息调度中心去查找相应的消息。 image.png

发布订阅的要素

  • 缓存队列,存放订阅者信息
  • 具有增加、删除订阅的能力
  • 状态改变时通知所有订阅者执行监听

浏览器中的EventLoop

完整事件环执行顺序

  • 从上至下执行所有的同步代码
  • 执行过程中将遇到宏任务与微任务添加至相应的队列
  • 同步代码执行完毕后,执行满足条件的微任务回调
  • 微任务队列执行完毕后,执行所有满足条件的宏任务回调
  • 循环事件环操作

注意:在执行每个宏任务前都要清空微任务队列

image.png image.png

Nodejs完整事件环

  • 执行同步代码,将不同的任务添加至相应的队列
  • 所有同步代码执行后会执行满足条件的微任务
  • 所有微任务执行后会执行timer队列中满足的宏任务
  • timer中的所有宏任务执行完成后会依次切换队列

注意:在完成队列切换前都要清空微任务队列

核心模块Stream

Node.js中文件操作系统和网络模块均实现了流接口,Node.js中的流就是处理流式数据的抽象接口。

应用程序中为什么使用流来处理数据?

常见的数据读取问题

  • 同步读取资源文件,用户需要等待数据读取完成
  • 资源文件最终一次性加载至内存,开销较大

为了解决上述问题,所有采用流的形式来操作数据 image.png image.png image.png

流处理数据的优势

  • 事件效率:流的分段处理可以同时操作多个数据
  • 空间效率:同一时间流无须占据大内存空间
  • 使用方便:流配合管理,扩展程序变得简单

Node.js内置了stream,它实现了流操作对象

Node.js中流的分类

image.png

可读流 (生产供程序消费数据的流)

可读流中的两种模式:

  • 流动模式 ( flowing ) :数据自动从系统底层读取,并通过事件,尽可能快地提供给应用程序。
  • 暂停模式 ( paused ),必须显式的调用 read() 读取数据。

image.png image.png image.png

可写流(用于消费数据的流)

image.png

Duplex(双工流,即可读又可写)

image.png

Transform(双工流)

image.png

write执行流程

  1. 第一次调用write方法时是将数据直接写入到文件中
  2. 第二次开始write方法就是将数据写入至缓存中
  3. 生产速度和消费速度是不一样的,一般情况下生产速度要比消费速度快很多
  4. 当读取数据大于缓存内存的时候,将可读流的模块修改为暂停模式
  5. 当数据生产者暂停之后,消费者会慢慢的笑话它内部缓存中的数据,知道可以再次被执行写入操作
  6. 当缓冲区可以继续写入数据时调用drain事件 image.png

image.png