nodejs流基类源码分析
时间:2022-07-22
本文章向大家介绍nodejs流基类源码分析,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
流是对数据生产,消费的一种抽象,今天先分析一下流基类的实现
const EE = require('events');
const util = require('util');
// 流的基类
function Stream() {
EE.call(this);
}
// 继承事件订阅分发的能力
util.inherits(Stream, EE);
流的基类只提供了一个函数就是pipe。用于实现管道化。这个方法代码比较多,分开说。
1 处理数据事件
function ondata(chunk) {
// 源流有数据到达,并且目的流可写
if (dest.writable) {
// 目的流过载并且源流实现了pause方法,那就暂停可读流的读取操作,等待目的流触发drain事件
if (false === dest.write(chunk) && source.pause) {
source.pause();
}
}
}
// 监听data事件,可读流有数据的时候,会触发data事件
source.on('data', ondata);
function ondrain() {
// 目的流可写了,并且可读流可读,切换成自动读取模式
if (source.readable && source.resume) {
source.resume();
}
}
// 监听drain事件,目的流可以消费数据了就会触发该事件
dest.on('drain', ondrain);
这是管道化时流控实现的地方,主要是利用了write返回值和drain事件。
流关闭/结束处理
// 目的流不是标准输出或标准错误,并且end不等于false
if (!dest._isStdio && (!options || options.end !== false)) {
// 源流没有数据可读了,执行end回调,告诉目的流,没有数据可读了
source.on('end', onend);
// 源流关闭了,执行close回调
source.on('close', onclose);
}
// 两个函数只会执行一次,也只会执行一个
var didOnEnd = false;
function onend() {
if (didOnEnd) return;
didOnEnd = true;
// 执行目的流的end函数,说明写数据完毕
dest.end();
}
function onclose() {
if (didOnEnd) return;
didOnEnd = true;
// 销毁目的流
if (typeof dest.destroy === 'function') dest.destroy();
}
这里是处理源流结束和关闭后,通知目的流的逻辑。
错误处理和事件清除
// remove all the event listeners that were added.
function cleanup() {
source.removeListener('data', ondata);
dest.removeListener('drain', ondrain);
source.removeListener('end', onend);
source.removeListener('close', onclose);
source.removeListener('error', onerror);
dest.removeListener('error', onerror);
source.removeListener('end', cleanup);
source.removeListener('close', cleanup);
dest.removeListener('close', cleanup);
}
function onerror(er) {
// 出错了,清除注册的事件,包括正在执行的onerror函数
cleanup();
// 如果用户没有监听流的error事件,则抛出错误,所以我们业务代码需要监听error事件
if (EE.listenerCount(this, 'error') === 0) {
throw er; // Unhandled stream error in pipe.
}
}
// 监听流的error事件
source.on('error', onerror);
dest.on('error', onerror);
// 源流关闭或者没有数据可读时,清除注册的事件
source.on('end', cleanup);
source.on('close', cleanup);
// 目的流关闭了也清除他注册的事件
dest.on('close', cleanup);
这里主要是处理了error事件和流关闭/结束/出错时清除订阅的事件。这就是流基类的所有逻辑。
- crontab命令详解
- hdu----(4308)Saving Princess claire_(搜索)
- spark2 sql读取数据源编程学习样例1
- golang的一个分页方法
- spark2 sql读取json文件的格式要求
- 容器化RDS|调度策略
- Go语言并发编程总结
- hdu------(4302)Holedox Eating(树状数组+二分)
- spark2的SparkSession思考与总结2:SparkSession有哪些函数及作用是什么
- GO语言并发编程之互斥锁、读写锁详解
- spark2.2 SparkSession思考与总结1
- 【译】Spring 官方教程:Spring Security 架构
- hdu----(4301)Divide Chocolate(状态打表)
- hdu------(4300)Clairewd’s message(kmp)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux系统下快速配置HugePages的完整步骤
- Laravel5.1 框架关联模型之后操作实例分析
- PHP实现的多进程控制demo示例
- 你可能不知道的一些linux文件权限管理办法
- Laravel框架路由与MVC实例详解
- python实现学生管理系统开发
- 使用 chkconfig 和 systemctl 命令启用或禁用 Linux 服务的办法
- PHP defined()函数的使用图文详解
- 详解在Linux中清空或删除大文件内容的5种办法
- php和redis实现秒杀活动的流程
- CentOS 7中搭建NFS文件共享存储服务的完整步骤
- PHP检测一个数组有没有定义的方法步骤
- Yii2.0框架模型多表关联查询示例
- Yii2.0框架模型添加/修改/删除数据操作示例
- thinkphp5.1框架容器与依赖注入实例分析