wengjq/Blog

through2 源码分析

wengjq opened this issue · 0 comments

var Transform = require('readable-stream').Transform
  , inherits  = require('util').inherits

// 创建一个类
function DestroyableTransform(opts) {
  // 调用父类构造函数
  Transform.call(this, opts)
  this._destroyed = false
}
// 继承 Transform 类的原型
inherits(DestroyableTransform, Transform)

// 添加 destroy 类方法
DestroyableTransform.prototype.destroy = function(err) {
  if (this._destroyed) return
  this._destroyed = true
  
  var self = this
  // 触发 destory 后,close 掉流
  process.nextTick(function() {
    if (err)
      self.emit('error', err)
    self.emit('close')
  })
}

// a noop _transform function
// 一个空的 _transform 函数
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
// 创建一个新的构造函数,用于主要的 through2.obj 和 through2.ctor
// 包含了处理 arguments 的逻辑
function through2 (construct) {
  return function (options, transform, flush) {
    // 实现第一个参数 options 可选
    if (typeof options == 'function') {
      flush     = transform
      transform = options
      options   = {}
    }

    // 如果 transform 不是一个函数,那么置 transform 为一个空的 _transform 函数(即不对流做任何处理)
    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!
// 主要的 export ,用于创建一个 transform 流
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) {
    // 实现无 new 调用
    if (!(this instanceof Through2))
      return new Through2(override)

    // 拓展 options
    this.options = Object.assign({}, options, override)

    // 继承 DestroyableTransform 的属性成员
    DestroyableTransform.call(this, this.options)
  }

  // 继承 DestroyableTransform 的原型链
  inherits(Through2, DestroyableTransform)

  // 添加 _transform 函数
  Through2.prototype._transform = transform

  // 添加 _flush 函数
  if (flush)
    Through2.prototype._flush = flush

  // 返回构造函数
  return Through2
})


module.exports.obj = through2(function (options, transform, flush) {
  // 由对象模式创建一个 transform 流
  var t2 = new DestroyableTransform(Object.assign({ objectMode: true, highWaterMark: 16 }, options))

  t2._transform = transform

  if (flush)
    t2._flush = flush

  return t2
})