【问题标题】:Multiple fs.writeFile on Node.jsNode.js 上的多个 fs.writeFile
【发布时间】:2021-06-22 12:35:02
【问题描述】:

直截了当,我在 Node.js 中运行一个 http 服务器,用于管理酒店的入住/退房信息,我使用“fs.writeFile”将所有 JSON 数据从内存写入同一个文件。 数据通常最大不超过 145kB,但是由于我每次从数据库获取更新时都需要编写它们,因此当对 fs.writeFile 的调用立即一个接一个地发生时,我会遇到数据丢失/错误的 JSON 格式。

目前我已经使用“fs.writeFileSync”解决了这个问题,但是我想听听更复杂的解决方案,而不是使用同步功能的简单/坏解决方案。 使用 fs.promises 会导致相同的错误,因为我必须再次调用 fs.promises。 根据 Node 的文档,多次调用 fs.writefile 或 fs.promises 是不安全的,他们建议使用文件流,但是目前这不是一个选项。

总而言之,在尝试任何重复的写入操作之前,我需要等待 fs.writeFile 正常结束,并且使用回调没有用,因为我不知道何时需要执行写入操作。 提前非常感谢您

【问题讨论】:

    标签: javascript node.js concurrency writefile


    【解决方案1】:

    我假设您的意思是在最后一个写入请求仍在写入时覆盖或截断文件。如果我是你,我会使用 promises API 并注意文档中的警告:

    It is unsafe to use fsPromises.writeFile() multiple times on the same file without waiting for the promise to be settled.

    您可以await 传统循环中的结果,或者非常小心地使用.then() 来“同步”您的回调,但如果您在事件循环中没有做任何其他事情,除了从您的数据库中读取和写入这个文件,你不妨使用writeFileSync 来保持简单/安全。异步 API(回调和 Promises)旨在让您的程序同时执行其他操作;如果这不是必需的并且异步 API 为您的代码增加了麻烦的复杂性,则只需使用同步 API。对于任何节点 API 或库函数都是如此,而不仅仅是 fs.writeFile

    还有一些库可以为您执行原子文件系统操作并抽象出实现细节,但我认为除非您更详细地描述您的用例,否则这些库对您来说可能是多余的。例如,为什么要尽可能快/频繁地将数据库以 JSON 格式转储到磁盘,而不是将内容保存在内存中或使用基于事件的增量更新(例如,具有原子性和一致性保证的真实本地数据库)。

    【讨论】:

    • 您好,bburhans,感谢您的回复!
    【解决方案2】:

    感谢您的回复! 由于我的应用程序主要是一个 http 服务器,是的,我做其他事情而不是简单的输入/输出,尽管请求数量不多。我将再次查看 promises 解决方案,但我第一次没有运气。

    为了解释更多,我有一个:function updateRoom(data){ ...update things in memory... writetoDisk(); } 和函数 writetoDisk(){ fsWriteFile(....) }

    使函数 writetoDisk 成为异步函数并在其中实现“等待”仍然不能解决问题,因为 updateRoom 函数将调用 writetoDisk 而不等待它结束。 “.then”方法无法实现,因为我的 updateRoom 被不断地动态调用。

    如果您碰巧知道关于 async-await 的 1-2 件事,非常欢迎您多解释一下,不过再次感谢!

    【讨论】:

    • 正确:使 writeToDisk() 成为 async function 将需要 awaiting 其结果或类似结果,这是有意的。 Promise 倾向于在async/await 代码中传播;如果某事依赖于Promise,您可能无法同步进行,直到它被解决或拒绝(无论哪种方式,fulfilled)。如果没有看到你的其余代码,我不能说为什么updateRoom 应该或不应该也是async,但可以考虑将其作为一种选择;这可能是一个不错的解决方案。
    • 您还暗示您在每次请求时都“颠簸”磁盘,而不是频繁更新内存中的对象,然后定期将内存刷新到磁盘(例如,使用setInterval 计时器转储您的 JSON )。为什么要将 JSON 写入磁盘,为什么如此频繁?它是绝对必要的,还是可以通过其他方式完成,例如一个合适的数据库还是只是一个最终一致的磁盘缓存?
    猜你喜欢
    • 2015-09-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2020-01-04
    • 1970-01-01
    • 2019-02-11
    • 2018-06-23
    • 1970-01-01
    相关资源
    最近更新 更多