繁体   English   中英

fs.promises.writeFile 在完成写入文件之前解析

[英]fs.promises.writeFile resolves before it finishes writing the file

我可能遗漏了一些明显的东西,但我花了几天时间寻找这个问题的解决方案,但没有找到任何解决方案。

我有一个 function,它接受一个 object,将它变成一个字符串,然后使用节点文件系统来保存它。 它应该等待文件在返回之前完成写入,但是,无论出于何种原因它没有。

相反,function 开始写入文件并调用 .then .then ()并在文件写入之前继续。 该文件确实完成了写入,但它只发生在 promise 已经被解析之后,因此,在 function 已经继续之后。

我正在使用 node.js 并且它是原生的fs.promises api 这是许多类似问题的建议(尽管其中许多来自 fs.promises 仍处于试验阶段)

代码:

const fs = require(`fs`);
const fsPromises = fs.promises;
const path = require (`path`);

var server = `test`;
const settings = {
  "name": "srvr.name",
  "serverId": "srvr.id",
  "ownerId": "srvr.ownerId",
  "prefix": "!",
  "roles":
  {
    "bot":
    {
      "id": "srvr.me.roles.highest.id",
      "name": "srvr.me.roles.highest.name"
    }
  }
};

saveSettings (server, settings);

Function:

async function saveSettings (server, settings) {

  const newSettings = await JSON.stringify (settings, null, `\t`);

  await fsPromises.writeFile (path.join (__dirname, `${server}.json`), newSettings)
  .then (console.log (`File Saved`));

  await console.log (fs.readFileSync (path.join (__dirname, `${server}.json`)));

  return console.log (`Settings Saved`);
}

预期结果:

File Saved
{
  "name": "srvr.name",
  "serverId": "srvr.id",
  "ownerId": "srvr.ownerId",
  "prefix": "!",
  "roles":
  {
    "bot":
    {
      "id": "srvr.me.roles.highest.id",
      "name": "srvr.me.roles.highest.name"
    }
  }
}
Settings Saved

实际结果:

File Saved
<Buffer 7b 0a 09 22 6e 61 6d 65 22 3a 20 22 73 72 76 72 2e 6e 61 6d 65 22 2c 0a 09 22 73 65 72 76 65 72 49 64 22 3a 20 22 73 72 76 72 2e 69 64 22 2c 0a 09 22 ... 150 more bytes>
Settings Saved

如您所见,当 function 尝试读取文件时,该文件仍在写入。

根据我的理解, fs.promises.writeFile 返回一个 promise 文件完成写入后将被解析,但它似乎并没有这样做。

我开始使用 fs.writeFile,但发现它没有返回 promise,因此 await 无法使用它。 我也尝试过 fs.writeFileSync,以防万一它可能起作用,但正如预期的那样,它没有。

我不知道 object 是否太大,因此文件写入时间太长,但据我所知,这应该不是问题,因为 promise 应该在文件写入后才能解析,不管需要多长时间。

我知道我可能在这里遗漏了一些非常明显的东西,无论是我遗漏了writeFile的工作方式,还是完全使用了错误的 function,但我不知道是什么。

如果它有用,这个 function 用于使用 Discord.js 的 Discord 机器人

提前致谢

await console.log (fs.readFileSync (path.join (__dirname, `${server}.json`)));

这不是你这样做的方式。

你想要

console.log(await fsPromises.readFileSync (path.join (__dirname, `${server}.json`)));

该承诺由 fsPromises.readFileSync 返回,而不是由 console.log 返回。

用户 Phix 在评论中指出了答案,但从好的方面来说,问题不在于文件仍在写入,而是默认情况下 readFile 返回一个buffer ,而不是一个字符串。 解决方案是将编码选项传递给 readFile/readFileSync,它可能应该是utf-8 为了更好地衡量,您还应该在编写文件时包括该编码。

当正在写入(异步)文件时,它会尝试读取(同步)文件。 因此,在您的情况下,无需异步编写文件。 您还不必要地使用await同步 function 调用。 我会通过使用同步写入和读取来编写如下 function。

function saveSettings (server, settings) {

  const newSettings = JSON.stringify (settings, null, `\t`);

  const settingsPath = path.join(__dirname, `${server}.json`);
  fs.writeFileSync(settingsPath, newSettings); // writes settings sync

  console.log(fs.readFileSync(settingsPath)); //read settings sync and print

  console.log (`Settings Saved`);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM