不推荐使用nodejs fs.exists()和fs.existsAsync(),但为什么我仍然可以将它与Node v4和v6一起使用

时间:2017-04-05 19:36:51

标签: node.js fs

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

它表示fs.exists()fs.existsAsync()已被弃用。

所以我的直觉是,如果我使用较新版本的NodeJ,它会引发错误。

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

3 个答案:

答案 0 :(得分:3)

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

  

所以我的直觉是,如果我使用较新版本的NodeJ,它会引发错误。

他们还没有犯错误。

  

然而,使用NodeJs v4.3.2和v6,我仍然看到fs.exists()工作。为什么会这样?

而且,从你问题的标题:

  

但为什么我仍然可以在Node v4和v6中使用它?

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

  

这是否意味着如果我从NodeJS v0.10.0迁移我的系统,我不一定要更新调用此类函数的依赖项,并且它是向后兼容的?

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

底线:如果您想要与未来版本兼容,请立即停止使用fs.exists()

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

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

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

然后,somefile是否存在的状态可能会在您运行fs.existsSync()调用的时间和执行代码的时间之间发生变化,该代码假定它知道该文件是否存在。这被称为“竞争条件”并且它被认为是非常糟糕的设计,因为它创造了极难再现的错误的可能性,这些错误可能偶尔会发生(可能是最难找到的错误类型)。

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

  

在调用之前使用fs.exists()检查文件是否存在   不建议fs.open()fs.readFile()fs.writeFile()。干   所以引入竞争条件,因为其他过程可能会改变   两个调用之间的文件状态。相反,用户代码应该   直接打开/读/写文件并处理引发的错误   文件不存在。

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

根据您通常尝试做的事情,非竞争条件的替代方法是尝试以某种独占访问方式打开文件。如果该文件存在,您将成功打开它,没有竞争条件。如果文件不存在,您只会收到错误,然后您可以处理该错误。在其他一些情况下,您只是尝试使用一种模式创建文件,如果模式已经存在则该文件将失败。这两种情况都在OS文件系统代码中使用原子比较,因此它们没有“竞争条件”。

您应该立即修复您的代码。如果您仍然不明白推荐的修补程序是什么,请发布使用fs.exists()的代码和周围的代码上下文,我们可以帮助您进行更好的设计。

答案 1 :(得分:1)

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

不要依赖它们向后兼容,甚至在各版本中都有相似的行为,即使它们存在也是如此。

答案 2 :(得分:1)

根据documentation

  

稳定性:0 - 已弃用此功能已知存在问题,并且计划进行更改。不要依赖它。使用此功能可能会导致警告。不应期望向后兼容。

换句话说,它可能会在任何时候退出或完全停止工作,恕不另行通知。如果/何时迁移,它可能有效,也可能无效。

对于它的价值,在其他软件中为多个主要版本保留已弃用的功能也不是非典型的。在OSS世界中,我看到过被弃用的功能,只要项目得以维持,就会持续下去。大概是因为维护者/用户群对弃用的功能有一些用处,因为它对于他们的用例来说已经足够好了(即使它不如它应该/可能的那样好,甚至在开发更新的API时)。

相关问题