fs: make unwatchFile() remove a specific listener
Before this commit, `fs.unwatchFile(path)` removed *all* listeners for `path`. The function is overloaded now: `fs.unwatchFile(path)` still removes all listeners, but `fs.unwatchFile(path, cb)` lets you remove a specific listener. Fixes #3660.
This commit is contained in:
parent
bf539f9bfd
commit
5b5362aa8d
@ -461,12 +461,16 @@ These stat objects are instances of `fs.Stat`.
|
||||
If you want to be notified when the file was modified, not just accessed
|
||||
you need to compare `curr.mtime` and `prev.mtime`.
|
||||
|
||||
|
||||
## fs.unwatchFile(filename)
|
||||
## fs.unwatchFile(filename, [listener])
|
||||
|
||||
Stability: 2 - Unstable. Use fs.watch instead, if available.
|
||||
|
||||
Stop watching for changes on `filename`.
|
||||
Stop watching for changes on `filename`. If `listener` is specified, only that
|
||||
particular listener is removed. Otherwise, *all* listeners are removed and you
|
||||
have effectively stopped watching `filename`.
|
||||
|
||||
Calling `fs.unwatchFile()` with a filename that is not being watched is a
|
||||
no-op, not an error.
|
||||
|
||||
## fs.watch(filename, [options], [listener])
|
||||
|
||||
|
16
lib/fs.js
16
lib/fs.js
@ -943,10 +943,18 @@ fs.watchFile = function(filename) {
|
||||
return stat;
|
||||
};
|
||||
|
||||
fs.unwatchFile = function(filename) {
|
||||
var stat;
|
||||
if (inStatWatchers(filename)) {
|
||||
stat = statWatchers[filename];
|
||||
fs.unwatchFile = function(filename, listener) {
|
||||
if (!inStatWatchers(filename)) return;
|
||||
|
||||
var stat = statWatchers[filename];
|
||||
|
||||
if (typeof listener === 'function') {
|
||||
stat.removeListener('change', listener);
|
||||
} else {
|
||||
stat.removeAllListeners('change');
|
||||
}
|
||||
|
||||
if (stat.listeners('change').length === 0) {
|
||||
stat.stop();
|
||||
statWatchers[filename] = undefined;
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ var fs = require('fs');
|
||||
|
||||
var watchSeenOne = 0;
|
||||
var watchSeenTwo = 0;
|
||||
var watchSeenThree = 0;
|
||||
|
||||
var startDir = process.cwd();
|
||||
var testDir = common.fixturesDir;
|
||||
@ -37,12 +38,16 @@ var filenameTwo = 'hasOwnProperty';
|
||||
var filepathTwo = filenameTwo;
|
||||
var filepathTwoAbs = path.join(testDir, filenameTwo);
|
||||
|
||||
var filenameThree = 'charm'; // because the third time is
|
||||
|
||||
|
||||
process.on('exit', function() {
|
||||
fs.unlinkSync(filepathOne);
|
||||
fs.unlinkSync(filepathTwoAbs);
|
||||
fs.unlinkSync(filenameThree);
|
||||
assert.equal(1, watchSeenOne);
|
||||
assert.equal(1, watchSeenTwo);
|
||||
assert.equal(2, watchSeenTwo);
|
||||
assert.equal(1, watchSeenThree);
|
||||
});
|
||||
|
||||
|
||||
@ -86,13 +91,38 @@ assert.throws(
|
||||
|
||||
assert.doesNotThrow(
|
||||
function() {
|
||||
fs.watchFile(filepathTwo, function(curr, prev) {
|
||||
fs.unwatchFile(filepathTwo);
|
||||
function a(curr, prev) {
|
||||
fs.unwatchFile(filepathTwo, a);
|
||||
++watchSeenTwo;
|
||||
});
|
||||
}
|
||||
function b(curr, prev) {
|
||||
fs.unwatchFile(filepathTwo, b);
|
||||
++watchSeenTwo;
|
||||
}
|
||||
fs.watchFile(filepathTwo, a);
|
||||
fs.watchFile(filepathTwo, b);
|
||||
}
|
||||
);
|
||||
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(filepathTwoAbs, 'pardner');
|
||||
}, 1000);
|
||||
|
||||
assert.doesNotThrow(
|
||||
function() {
|
||||
function a(curr, prev) {
|
||||
assert.ok(0); // should not run
|
||||
}
|
||||
function b(curr, prev) {
|
||||
fs.unwatchFile(filenameThree, b);
|
||||
++watchSeenThree;
|
||||
}
|
||||
fs.watchFile(filenameThree, a);
|
||||
fs.watchFile(filenameThree, b);
|
||||
fs.unwatchFile(filenameThree, a);
|
||||
}
|
||||
);
|
||||
|
||||
setTimeout(function() {
|
||||
fs.writeFileSync(filenameThree, 'pardner');
|
||||
}, 1000);
|
||||
|
Loading…
x
Reference in New Issue
Block a user