From fe12cc07b3ef37148bce9765a506e20f21a5bd86 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 1 Feb 2021 15:53:36 -0800 Subject: [PATCH] fs: add fsPromises.watch() An alternative to `fs.watch()` that returns an `AsyncIterator` ```js const { watch } = require('fs/promises'); (async () => { const ac = new AbortController(); const { signal } = ac; setTimeout(() => ac.abort(), 10000); const watcher = watch('file.txt', { signal }); for await (const { eventType, filename } of watcher) { console.log(eventType, filename); } })() ``` Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/37179 Reviewed-By: Benjamin Gruenbaum --- doc/api/fs.md | 53 ++++++++++- lib/internal/fs/promises.js | 2 + lib/internal/fs/watchers.js | 119 +++++++++++++++++++++++- test/parallel/test-bootstrap-modules.js | 3 + test/parallel/test-fs-promises-watch.js | 116 +++++++++++++++++++++++ 5 files changed, 286 insertions(+), 7 deletions(-) create mode 100644 test/parallel/test-fs-promises-watch.js diff --git a/doc/api/fs.md b/doc/api/fs.md index b37539960f32ac..2143679900651f 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1181,6 +1181,55 @@ The `atime` and `mtime` arguments follow these rules: * If the value can not be converted to a number, or is `NaN`, `Infinity` or `-Infinity`, an `Error` will be thrown. +### `fsPromises.watch(filename[, options])` + + +* `filename` {string|Buffer|URL} +* `options` {string|Object} + * `persistent` {boolean} Indicates whether the process should continue to run + as long as files are being watched. **Default:** `true`. + * `recursive` {boolean} Indicates whether all subdirectories should be + watched, or only the current directory. This applies when a directory is + specified, and only on supported platforms (See [caveats][]). **Default:** + `false`. + * `encoding` {string} Specifies the character encoding to be used for the + filename passed to the listener. **Default:** `'utf8'`. + * `signal` {AbortSignal} An {AbortSignal} used to signal when the watcher + should stop. +* Returns: {AsyncIterator} of objects with the properties: + * `eventType` {string} The type of change + * `filename` {string|Buffer} The name of the file changed. + +Returns an async iterator that watches for changes on `filename`, where `filename` +is either a file or a directory. + +```js +const { watch } = require('fs/promises'); + +const ac = new AbortController(); +const { signal } = ac; +setTimeout(() => ac.abort(), 10000); + +(async () => { + try { + const watcher = watch(__filename, { signal }); + for await (const event of watcher) + console.log(event); + } catch (err) { + if (err.name === 'AbortError') + return; + throw err; + } +})(); +``` + +On most platforms, `'rename'` is emitted whenever a filename appears or +disappears in the directory. + +All the [caveats][] for `fs.watch()` also apply to `fsPromises.watch()`. + ### `fsPromises.writeFile(file, data[, options])`