diff --git a/lib/nodefs-handler.js b/lib/nodefs-handler.js index d8c1f08a..4d3d6e5e 100644 --- a/lib/nodefs-handler.js +++ b/lib/nodefs-handler.js @@ -4,6 +4,7 @@ var fs = require('fs'); var sysPath = require('path'); var readdirp = require('readdirp'); var isBinaryPath = require('is-binary-path'); +var debounce = require('lodash.debounce'); // fs.watch helpers @@ -341,15 +342,12 @@ function(dir, stats, initialAdd, depth, target, wh, callback) { parentDir.add(sysPath.basename(dir)); this._getWatchedDir(dir); + var debouncedRead; + var read = function(directory, initialAdd, done) { // Normalize the directory name on Windows directory = sysPath.join(directory, ''); - if (!wh.hasGlob) { - var throttler = this._throttle('readdir', directory, 1000); - if (!throttler) return; - } - var previous = this._getWatchedDir(wh.path); var current = []; @@ -380,9 +378,11 @@ function(dir, stats, initialAdd, depth, target, wh, callback) { this._addToNodeFs(path, initialAdd, wh, depth + 1); } }.bind(this)).on('end', function() { - if (throttler) throttler.clear(); if (done) done(); + // Run any pending reads that may be queued + debouncedRead.flush(); + // Files that absent in current directory snapshot // but present in previous emit `remove` event // and are removed from @watched[directory]. @@ -401,6 +401,13 @@ function(dir, stats, initialAdd, depth, target, wh, callback) { }.bind(this)).on('error', this._handleError.bind(this)); }.bind(this); + // Create a debounced version of read + debouncedRead = debounce(read, 1000, { + leading: true, + trailing: true, + maxWait: 1000 + }); + var closer; if (this.options.depth == null || depth <= this.options.depth) { @@ -408,13 +415,21 @@ function(dir, stats, initialAdd, depth, target, wh, callback) { closer = this._watchWithNodeFs(dir, function(dirPath, stats) { // if current directory is removed, do nothing if (stats && stats.mtime.getTime() === 0) return; - - read(dirPath, false); + debouncedRead(dirPath, false); }); } else { callback(); } - return closer; + + // Close function that calls fs closer and cancels any pending debounced reads + return function () { + if (closer) { + closer(); + } + + // Cancel any pending reads that may be queued + debouncedRead.cancel(); + }; }; // Private method: Handle added file, directory, or glob pattern. diff --git a/package.json b/package.json index ada45c10..0ad10690 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "inherits": "^2.0.1", "is-binary-path": "^1.0.0", "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", "normalize-path": "^2.1.1", "path-is-absolute": "^1.0.0", "readdirp": "^2.0.0",