Reputation: 1399
Is there a way to fire only once on changing directory content with Node.js fs.watch
? By changing directory content I mean adding/deleting bunch of files from it ?
In other words I expect fs.watch
to fire on the first event of the first file and ignore any other events for particular changing dir content cycle.
I was able to do this only with fs.watchFile
But node guys recommend to use fs.watch
if possible.
Note: fs.watch() is more efficient than fs.watchFile and fs.unwatchFile. fs.watch should be used instead of fs.watchFile and fs.unwatchFile when possible.
https://nodejs.org/docs/latest/api/fs.html#fs_fs_watchfile_filename_options_listener
Upvotes: 2
Views: 1799
Reputation: 1399
Yury Tarabanko patricianly answered this question earlier, but shortly after deleted his answer:
You simply stop watching on the first call
const watcher = fs.watch(somePath, (ev, file) => { watcher.close() // logic goes here console.log(`${ev} ${file}`) })
With resurrecting watcher after closing it, we will have 1 shot recurrent behavior as asked in the question:
const fs = require('fs')
let dir = './watch1'
function watchOnce()
{
const watcher = fs.watch(dir, (evt, file) => {
watcher.close()
// logic goes here
console.log(Date(), evt, file)
// resurrecting watcher after 1 sec
setTimeout(watchOnce, 1000)
})
}
watchOnce()
Testing
Creating and deleting 10,000 files 5 times in a raw with 1 seconds delay in between:
$ for i in {1..5}; do touch {1..10000}; sleep 1; rm {1..10000}; sleep 1; done
Verifying that watcher fired exactly 10 times (5 for creating 10,000 files and 5 for deleting 10,000 files):
$ node watchers.js
Wed Jun 07 2017 12:01:44 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:46 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:47 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:49 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:50 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:52 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:53 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:55 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:56 GMT+0300 (EEST) rename 1
Wed Jun 07 2017 12:01:58 GMT+0300 (EEST) rename 1
I will not marking my answer as accepted, since credits mostly goes to Yury for his watcher.close()
idea. And maybe someone else will write more neat solution, since I am not big fun using delay in the function.
Upvotes: 4