through2 本质上是一种transform的流
被封装更好地操作流
var Transform = require('readable-stream/transform')
, inherits = require('util').inherits
, xtend = require('xtend')
function DestroyableTransform(opts) {
// 继承Transform
Transform.call(this, opts)
this._destroyed = false
}
inherits(DestroyableTransform, Transform)
// 原型接口destory 用来关闭流
DestroyableTransform.prototype.destroy = function(err) {
if (this._destroyed) return
this._destroyed = true
var self = this
process.nextTick(function() {
if (err)
self.emit('error', err)
self.emit('close')
//events的使用
})
}
// a noop _transform function
// 空操作
function noop (chunk, enc, callback) {
callback(null, chunk)
}
// create a new export function, used by both the main export and
// the .ctor export, contains common logic for dealing with arguments
// 返回一个导出的函数接口
function through2 (construct) {
// 返回使用的匿名函数
return function (options, transform, flush) {
if (typeof options == 'function') {
flush = transform
transform = options
options = {}
}
// 这种匿名函数我们一般可以用来做二次判断触发
if (typeof transform != 'function')
transform = noop
if (typeof flush != 'function')
flush = null
return construct(options, transform, flush)
}
}
// main export, just make me a transform stream!
// 主要出口,使用through2返回一个DestroyTransform实例
module.exports = through2(function (options, transform, flush) {
var t2 = new DestroyableTransform(options)
t2._transform = transform
if (flush)
t2._flush = flush
return t2
})
// make me a reusable prototype that I can `new`, or implicitly `new`
// with a constructor call
// 对外暴露一个可以直接 new (或者不加 new)来创建实例的的构造函数
module.exports.ctor = through2(function (options, transform, flush) {
function Through2 (override) {
if (!(this instanceof Through2))
// 这里就是直接自动new
return new Through2(override)
this.options = xtend(options, override)
// 添加配置
DestroyableTransform.call(this, this.options)
}
inherits(Through2, DestroyableTransform)
Through2.prototype._transform = transform
if (flush)
Through2.prototype._flush = flush
return Through2
})
// Object模式的简单封装
module.exports.obj = through2(function (options, transform, flush) {
var t2 = new DestroyableTransform(xtend({ objectMode: true, highWaterMark: 16 }, options))
t2._transform = transform
if (flush)
t2._flush = flush
return t2
})
xtend lib //简单的继承 两种,一种可变 一种不可变
module.exports = extend
var hasOwnProperty = Object.prototype.hasOwnProperty;
// 缓存老套路。优化性能
function extend(target) {
// 这里有个有意思的地方。target第一个拿进来。在多个参数的情况下。下面从arguments[1]开始取,而下面可以直接使用target,而不用再声明一下变量
for (var i = 1; i < arguments.length//这块其实可以缓存长度的; i++) {
var source = arguments[i]
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
// 判断当前实例是否存在属性
// 有则添加到target上。无则跳过,支持覆盖
target[key] = source[key]
}
}
}
return target
}
不可变。
module.exports = extend
var hasOwnProperty = Object.prototype.hasOwnProperty;
function extend() {
// 与原先不同的是,这里使用了一份初始化的对象引用来作为容器承载
// 其余没有不同
var target = {}
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i]
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
target[key] = source[key]
}
}
}
return target
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。