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
|
If you want to be notified when the file was modified, not just accessed
|
||||||
you need to compare `curr.mtime` and `prev.mtime`.
|
you need to compare `curr.mtime` and `prev.mtime`.
|
||||||
|
|
||||||
|
## fs.unwatchFile(filename, [listener])
|
||||||
## fs.unwatchFile(filename)
|
|
||||||
|
|
||||||
Stability: 2 - Unstable. Use fs.watch instead, if available.
|
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])
|
## fs.watch(filename, [options], [listener])
|
||||||
|
|
||||||
|
16
lib/fs.js
16
lib/fs.js
@ -943,10 +943,18 @@ fs.watchFile = function(filename) {
|
|||||||
return stat;
|
return stat;
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.unwatchFile = function(filename) {
|
fs.unwatchFile = function(filename, listener) {
|
||||||
var stat;
|
if (!inStatWatchers(filename)) return;
|
||||||
if (inStatWatchers(filename)) {
|
|
||||||
stat = statWatchers[filename];
|
var stat = statWatchers[filename];
|
||||||
|
|
||||||
|
if (typeof listener === 'function') {
|
||||||
|
stat.removeListener('change', listener);
|
||||||
|
} else {
|
||||||
|
stat.removeAllListeners('change');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat.listeners('change').length === 0) {
|
||||||
stat.stop();
|
stat.stop();
|
||||||
statWatchers[filename] = undefined;
|
statWatchers[filename] = undefined;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ var fs = require('fs');
|
|||||||
|
|
||||||
var watchSeenOne = 0;
|
var watchSeenOne = 0;
|
||||||
var watchSeenTwo = 0;
|
var watchSeenTwo = 0;
|
||||||
|
var watchSeenThree = 0;
|
||||||
|
|
||||||
var startDir = process.cwd();
|
var startDir = process.cwd();
|
||||||
var testDir = common.fixturesDir;
|
var testDir = common.fixturesDir;
|
||||||
@ -37,12 +38,16 @@ var filenameTwo = 'hasOwnProperty';
|
|||||||
var filepathTwo = filenameTwo;
|
var filepathTwo = filenameTwo;
|
||||||
var filepathTwoAbs = path.join(testDir, filenameTwo);
|
var filepathTwoAbs = path.join(testDir, filenameTwo);
|
||||||
|
|
||||||
|
var filenameThree = 'charm'; // because the third time is
|
||||||
|
|
||||||
|
|
||||||
process.on('exit', function() {
|
process.on('exit', function() {
|
||||||
fs.unlinkSync(filepathOne);
|
fs.unlinkSync(filepathOne);
|
||||||
fs.unlinkSync(filepathTwoAbs);
|
fs.unlinkSync(filepathTwoAbs);
|
||||||
|
fs.unlinkSync(filenameThree);
|
||||||
assert.equal(1, watchSeenOne);
|
assert.equal(1, watchSeenOne);
|
||||||
assert.equal(1, watchSeenTwo);
|
assert.equal(2, watchSeenTwo);
|
||||||
|
assert.equal(1, watchSeenThree);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -86,13 +91,38 @@ assert.throws(
|
|||||||
|
|
||||||
assert.doesNotThrow(
|
assert.doesNotThrow(
|
||||||
function() {
|
function() {
|
||||||
fs.watchFile(filepathTwo, function(curr, prev) {
|
function a(curr, prev) {
|
||||||
fs.unwatchFile(filepathTwo);
|
fs.unwatchFile(filepathTwo, a);
|
||||||
++watchSeenTwo;
|
++watchSeenTwo;
|
||||||
});
|
}
|
||||||
|
function b(curr, prev) {
|
||||||
|
fs.unwatchFile(filepathTwo, b);
|
||||||
|
++watchSeenTwo;
|
||||||
|
}
|
||||||
|
fs.watchFile(filepathTwo, a);
|
||||||
|
fs.watchFile(filepathTwo, b);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
fs.writeFileSync(filepathTwoAbs, 'pardner');
|
fs.writeFileSync(filepathTwoAbs, 'pardner');
|
||||||
}, 1000);
|
}, 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