nodejs fs.exists() 和 fs.existsAsync() 已弃用,但为什么我仍然可以将它用于 Node v4 和 v6

nodejs fs.exists() and fs.existsAsync() are deprecated, but why can I still use it with Node v4 and v6

我正在阅读这里的 Nodejs 文档 https://nodejs.org/api/fs.html#fs_fs_exists_path_callback

它说 fs.exists()fs.existsAsync() 已弃用。

所以我的直觉是,如果我使用较新版本的 NodeJs,它会抛出错误。

但是,同时使用 NodeJs v4.3.2 和 v6,我仍然看到 fs.exists() 正常工作。为什么会这样?这是否意味着如果我从 NodeJS v0.10.0 迁移我的系统,我不必更新调用此类函数的依赖项,并且它是向后兼容的?

Node.js 中的稳定性级别 0(或已弃用)意味着它可以随时删除,但不一定是下一个版本。

不要依赖它们向后兼容,甚至即使它们存在也不要依赖于跨版本的相似行为。

根据 documentation

Stability: 0 - Deprecated This feature is known to be problematic, and changes are planned. Do not rely on it. Use of the feature may cause warnings. Backwards compatibility should not be expected.

换句话说,它可能随时退出或以其他方式完全停止工作,恕不另行通知。它可能会或可能不会 if/when 您迁移。

就其价值而言,其他软件中的多个主要版本也保留已弃用的功能并不少见。在 OSS 世界中,我看到过在项目维护期间一直存在的已弃用功能。大概是因为 maintainer/user 基础对已弃用的功能有一些用处,因为它对他们的用例来说已经足够好了(即使它不如 should/could 曾经那么好,即使更新的 API 已开发)。

这意味着 node.js 开发背后的社区建议不要使用此功能 现在 因为它有问题,他们可能会在将来的某个时候摆脱它以迫使人们停止使用它。

So my intuition would be that it will throw an error if I am using a newer version of NodeJs.

他们还没有让它抛出错误。

However, using both NodeJs v4.3.2 and v6, I still see the fs.exists() working. why is it so?

而且,根据您的问题标题:

but why can I still use it with Node v4 and v6?

因为虽然他们现在建议不要使用它,但他们还没有删除它。

does that mean that If I migrate my system from NodeJS v0.10.0, I don't necessarily have to update my dependencies that is invoking such function, and it's backward compatible?

没有。 node.js 背后的社区告诉您,他们保留在任何未来版本中删除这两个功能的权利。

底线:如果您希望与未来版本兼容,请立即停止使用这两个 fs.exists()


fs.exists() 也与其他 node.js 异步 API 不一致,因为回调不遵循 fn(err, data) 的典型调用约定。它没有 err 参数,这使它变得古怪。

您可能还想了解它们使用起来有问题的原因。现代操作系统是一个 multi-tasking 系统,文件系统是潜在许多进程之间的共享资源。这意味着如果您这样做:

if (fs.existsSync("somefile")) {
    // execute some code when somefile does exist 
} else {
    // execute some code when somefile does not exist
}

然后,某些文件是否存在的状态可能会在您 运行 调用 fs.existsSync() 和您执行假设它知道该文件是否存在的代码之间发生变化.这就是所谓的 "race condition",它被认为是非常糟糕的设计,因为它有可能产生极度 hard-to-reproduce 的错误,这些错误可能偶尔会出现(可能是试图找到的最糟糕的错误类型)。

直接从 fs.exists() 的 node.js 文档中注意这一点:

Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist.

如果您使用的是异步版本 fs.exists(),那么竞争条件会更糟,因为您自己的 node.js 代码甚至会更改文件的状态,因为您的 if/else逻辑 运行s.

根据您通常要执行的操作,non-race-condition 替代方法是尝试以某种独占访问权限打开文件。如果该文件存在,您将成功打开它而不会出现竞争条件。如果该文件不存在,您只会得到一个错误,然后您可以处理该错误。在其他一些情况下,您只是尝试使用一种模式创建文件,如果它已经存在,则会失败。这两种情况都在 OS 文件系统代码中使用原子比较,因此它们没有 "race conditions"。

您现在应该修复您的代码。如果您仍然不明白建议的修复是什么,请 post 您使用 fs.exists() 的代码和周围的代码上下文,我们可以帮助您进行更好的设计。