You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
blockvote/node_modules/destroy/index.js

285 lines
8.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*!
* destroy
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015-2022 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'; // 启用严格模式
/**
* 模块依赖项。
* @private
*/
var EventEmitter = require('events').EventEmitter; // 引入 EventEmitter 类
var ReadStream = require('fs').ReadStream; // 引入文件读取流
var Stream = require('stream'); // 引入流模块
var Zlib = require('zlib'); // 引入 zlib 模块,用于压缩和解压缩流
/**
* 模块导出。
* @public
*/
module.exports = destroy; // 导出 destroy 函数
/**
* 销毁给定的流,并可选择抑制未来的 `error` 事件。
*
* @param {object} stream - 要销毁的流对象。
* @param {boolean} suppress - 是否抑制错误事件。
* @public
*/
function destroy(stream, suppress) {
// 判断流的类型并调用相应的销毁函数
if (isFsReadStream(stream)) {
destroyReadStream(stream); // 如果是文件读取流,调用销毁文件读取流的函数
} else if (isZlibStream(stream)) {
destroyZlibStream(stream); // 如果是 zlib 流,调用销毁 zlib 流的函数
} else if (hasDestroy(stream)) {
stream.destroy(); // 如果流具有 destroy 方法,则直接调用它
}
// 如果流是事件发射器并且 suppress 为 true移除所有错误事件监听器
if (isEventEmitter(stream) && suppress) {
stream.removeAllListeners('error'); // 移除所有 'error' 事件监听器
stream.addListener('error', noop); // 添加一个空的错误处理函数
}
return stream; // 返回被销毁的流
}
/**
* 销毁 ReadStream。
*
* @param {object} stream - 要销毁的 ReadStream 对象。
* @private
*/
function destroyReadStream(stream) {
stream.destroy(); // 调用流的 destroy 方法
// 如果流具有 close 方法,添加 'open' 事件的监听器
if (typeof stream.close === 'function') {
// node.js 核心 bug 的解决方法
stream.on('open', onOpenClose); // 在流打开时调用 onOpenClose 函数
}
}
/**
* 关闭 Zlib 流。
*
* Zlib 流在 Node.js 4.5.5 之前的实现中,
* 当 zlib 遇到错误时,.close() 方法存在bug。
*
* @param {object} stream - 要关闭的 Zlib 流对象。
* @private
*/
function closeZlibStream(stream) {
// 如果流有错误,处理流的关闭
if (stream._hadError === true) {
var prop = stream._binding === null
? '_binding' // 选择属性
: '_handle';
// 创建一个关闭函数,将属性设置为 null
stream[prop] = {
close: function () { this[prop] = null; }
};
}
stream.close(); // 调用流的 close 方法
}
/**
* Destroy a Zlib stream.
*
* Zlib streams don't have a destroy function in Node.js 6. On top of that
* simply calling destroy on a zlib stream in Node.js 8+ will result in a
* memory leak. So until that is fixed, we need to call both close AND destroy.
*
* PR to fix memory leak: https://github.com/nodejs/node/pull/23734
*
* In Node.js 6+8, it's important that destroy is called before close as the
* stream would otherwise emit the error 'zlib binding closed'.
*
* @param {object} stream
* @private
*/
/**
* 销毁 Zlib 流。
*
* @param {object} stream - 要销毁的 Zlib 流对象。
*/
function destroyZlibStream(stream) {
// 检查流是否具有 destroy 方法
if (typeof stream.destroy === 'function') {
// node.js 核心 bug 的解决方法
// istanbul ignore if: node.js 0.8
if (stream._binding) {
// 处理 Node.js 版本小于 0.10.0 的情况
stream.destroy(); // 调用流的 destroy 方法
// 如果流正在处理数据
if (stream._processing) {
stream._needDrain = true; // 标记需要排空
stream.once('drain', onDrainClearBinding); // 一旦排空,调用 onDrainClearBinding 函数
} else {
stream._binding.clear(); // 清除绑定
}
} else if (stream._destroy && stream._destroy !== Stream.Transform.prototype._destroy) {
// 处理 Node.js 版本大于等于 12或 11.1.0,或 10.15.1 的情况
stream.destroy(); // 调用流的 destroy 方法
} else if (stream._destroy && typeof stream.close === 'function') {
// 处理 Node.js 版本为 7 或 8 的情况
stream.destroyed = true; // 标记流为已销毁
stream.close(); // 调用流的 close 方法
} else {
// 备用方案
// istanbul ignore next
stream.destroy(); // 调用流的 destroy 方法
}
} else if (typeof stream.close === 'function') {
// 处理 Node.js 版本小于 8 的备用方案
closeZlibStream(stream); // 调用关闭 zlib 流的函数
}
}
/**
* 确定流是否具有 destroy 方法。
* @private
*/
function hasDestroy(stream) {
return stream instanceof Stream && // 检查流是否是 Stream 的实例
typeof stream.destroy === 'function'; // 检查流是否具有 destroy 方法
}
/**
* 确定 val 是否是 EventEmitter。
* @private
*/
function isEventEmitter(val) {
return val instanceof EventEmitter; // 检查 val 是否是 EventEmitter 的实例
}
/**
* 确定流是否是 fs.ReadStream 流。
* @private
*/
function isFsReadStream(stream) {
return stream instanceof ReadStream; // 检查流是否是 ReadStream 的实例
}
/**
* 确定流是否是 Zlib 流。
* @private
*/
function isZlibStream(stream) {
// 检查流是否是 Zlib 的不同类型的实例
return stream instanceof Zlib.Gzip ||
stream instanceof Zlib.Gunzip ||
stream instanceof Zlib.Deflate ||
stream instanceof Zlib.DeflateRaw ||
stream instanceof Zlib.Inflate ||
stream instanceof Zlib.InflateRaw ||
stream instanceof Zlib.Unzip;
}
/**
* No-op function.
* @private
*/
/**
* 销毁 Zlib 流。
*
* @param {object} stream - 要销毁的 Zlib 流对象。
*/
function destroyZlibStream(stream) {
// 检查流是否具有 destroy 方法
if (typeof stream.destroy === 'function') {
// node.js 核心 bug 的解决方法
// istanbul ignore if: node.js 0.8
if (stream._binding) {
// 处理 Node.js 版本小于 0.10.0 的情况
stream.destroy(); // 调用流的 destroy 方法
// 如果流正在处理数据
if (stream._processing) {
stream._needDrain = true; // 标记需要排空
stream.once('drain', onDrainClearBinding); // 一旦排空,调用 onDrainClearBinding 函数
} else {
stream._binding.clear(); // 清除绑定
}
} else if (stream._destroy && stream._destroy !== Stream.Transform.prototype._destroy) {
// 处理 Node.js 版本大于等于 12或 11.1.0,或 10.15.1 的情况
stream.destroy(); // 调用流的 destroy 方法
} else if (stream._destroy && typeof stream.close === 'function') {
// 处理 Node.js 版本为 7 或 8 的情况
stream.destroyed = true; // 标记流为已销毁
stream.close(); // 调用流的 close 方法
} else {
// 备用方案
// istanbul ignore next
stream.destroy(); // 调用流的 destroy 方法
}
} else if (typeof stream.close === 'function') {
// 处理 Node.js 版本小于 8 的备用方案
closeZlibStream(stream); // 调用关闭 zlib 流的函数
}
}
/**
* 确定流是否具有 destroy 方法。
* @private
*/
function hasDestroy(stream) {
return stream instanceof Stream && // 检查流是否是 Stream 的实例
typeof stream.destroy === 'function'; // 检查流是否具有 destroy 方法
}
/**
* 确定 val 是否是 EventEmitter。
* @private
*/
function isEventEmitter(val) {
return val instanceof EventEmitter; // 检查 val 是否是 EventEmitter 的实例
}
/**
* 确定流是否是 fs.ReadStream 流。
* @private
*/
function isFsReadStream(stream) {
return stream instanceof ReadStream; // 检查流是否是 ReadStream 的实例
}
/**
* 确定流是否是 Zlib 流。
* @private
*/
function isZlibStream(stream) {
// 检查流是否是 Zlib 的不同类型的实例
return stream instanceof Zlib.Gzip ||
stream instanceof Zlib.Gunzip ||
stream instanceof Zlib.Deflate ||
stream instanceof Zlib.DeflateRaw ||
stream instanceof Zlib.Inflate ||
stream instanceof Zlib.InflateRaw ||
stream instanceof Zlib.Unzip;
}