簡體   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