fs.watch源码
watch方法的源码中的逻辑,和watchFile方法的源码逻辑基本相同,只是继承的构造函数不同而已。下面就看下源码的实现吧。
// watch方法使用到的构造函数
function FSWatcher() {
// 继承事件模块中的实例内部属性和方法
EventEmitter.call(this); // 缓存this对象,在闭包的回调函数中使用
var self = this;
// 获取C++中实现的FSEvent构造函数,
// 该获取是否应该放到函数外部去,优化代码
// 就像在StatWatcher构造函数内部的binding.StatWatcher();方法
var FSEvent = process.binding('fs_event_wrap').FSEvent;
this._handle = new FSEvent();
this._handle.owner = this;
//绑定回调,onchange事件
this._handle.onchange = function(status, event, filename) {
// event变了好像是有问题的,我本地测试,event的值一直是“rename”
// 根据status的值,作出不同的处理
if (status < 0) {
self._handle.close();
self.emit('error', errnoException(status, 'watch'));
} else {
self.emit('change', event, filename);
}
};
}
// FSWatcher的原型链继承EventEmitter构造函数的原型链的属性和方法
util.inherits(FSWatcher, EventEmitter);
// start方法,当初始化构造函数之后,要执行该方法,才能开始监听filename指向的目录或者文件
FSWatcher.prototype.start = function(filename, persistent, recursive) {
nullCheck(filename);
//调用C++中实现的方法,开始执行监听动作
var err = this._handle.start(pathModule._makeLong(filename),
persistent,
recursive);
// 如果监听时,没有能正确的执行,则关闭该实例,并且抛出一个异常
if (err) {
this._handle.close();
throw errnoException(err, 'watch');
}
};
// 关闭监听
FSWatcher.prototype.close = function() {
this._handle.close();
};
fs.watch = function(filename) {
// 判断filename是否合法
nullCheck(filename);
var watcher;
var options;
var listener;
// 判断是否有参数
// 初始化参数和回调函数
if (util.isObject(arguments[1])) {
options = arguments[1];
listener = arguments[2];
} else {
options = {};
listener = arguments[1];
}
// 给persistent和recursive设置默认值,这里我依然觉得是可以优化的。
// 既然在后面只是使用persistent和recursive,那么为何不定义着凉变量
// var persistent = options.persistent,
// recursive = options.recursive;
// if(util.isUndefined(persistent)) persistent = true;
// if(util.isUndefined(recursive)) recursive = false;
// ...
// watcher.start(filename,persistent,recursive);









