我需要根據傳遞給自定義 writeData() 函式的物件組成的陣列撰寫多個動態變化的檔案。該陣列由包含檔案名和要寫入的資料的物件組成,如下所示:
[
{
file_name: "example.json",
dataObj,
},
{
file_name: "example2.json",
dataObj,
},
{
file_name: "example3.json",
dataObj,
},
{
file_name: "example4.json",
dataObj,
},
];
我目前的方法是映射這個陣列并將新資料讀 寫到每個檔案:
array.map((entry) => {
fs.readFile(
entry.file_name,
"utf8",
(err, unparsedData) => {
if (err) console.log(err);
else {
var parsedData = JSON.parse(unparsedData);
parsedData.data.push(entry.dataObj);
const parsedDataJSON = JSON.stringify(parsedData, null, 2);
fs.writeFile(
entry.file_name,
parsedDataJSON,
"utf8",
(err) => {
if (err) console.log(err);
}
);
}
}
);
});
然而,這不起作用。只有一小部分資料被寫入這些檔案,而且檔案通常沒有以 json 格式正確寫入(我認為這是因為兩個 writeFile 行程同時寫入同一個檔案,這會破壞檔案)。顯然,這并不像我預期的那樣作業。
The multiple ways I have tried to resolve this problem consisted of attempting to make the fs.writeFile synchronous (delay the map loop, allowing each process to finish before moving to the next entry), but this is not a good practice as synchronous processes hang up the entire app. I have also looked into implementing promises but to no avail. I am a new learner to nodejs so apologies for missed details/information. Any help is appreciated!
uj5u.com熱心網友回復:
如果更改任何內容,同一檔案通常會在陣列中多次列出。
嗯,這改變了一切。您應該在原始問題中證明這一點。如果是這種情況,那么您必須對回圈中的每個單獨檔案進行排序,以便在前進到下一個之前完成一個檔案。為了防止寫入同一個檔案之間發生沖突,您必須確保兩件事:
- 您對回圈中的每個檔案進行排序,以便下一個檔案在前一個檔案完成之前不會開始。
- 當它仍在運行時,您不會再次呼叫此代碼。
您可以像這樣向自己保證第一項:
async function processFiles(array) {
for (let entry of array) {
const unparsedData = await fs.promises.readFile(entry.file_name, "utf8");
const parsedData = JSON.parse(unparsedData);
parsedData.data.push(entry.dataObj);
const json = JSON.stringify(parsedData, null, 2);
await fs.promise.writeFile(entry.file_name, json, "utf8");
}
}
如果其中任何一個出現錯誤,這將中止回圈。如果你想讓它繼續寫其他的,你可以在try/catch內部添加一個:
async function processFiles(array) {
let firstError;
for (let entry of array) {
try {
const unparsedData = await fs.promises.readFile(entry.file_name, "utf8");
const parsedData = JSON.parse(unparsedData);
parsedData.data.push(entry.dataObj);
const json = JSON.stringify(parsedData, null, 2);
await fs.promise.writeFile(entry.file_name, json, "utf8");
} catch (e) {
// log error and continue with the rest of the loop
if (!firstError) {
firstError = e;
}
console.log(e);
}
}
// make sure we communicate back any error that happened
if (firstError) {
throw firstError;
}
}
To assure yourself of the second point above, you will have to either not use a setInterval() (replace it with a setTimeout() that you set when the promise that processFiles()resolves or make absolutely sure that the setInterval() time is long enough that it will never fire before processFiles() is done.
Also, make absolutely sure that you are not modifying the array used in this function while that function is running.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/424472.html
上一篇:for回圈重復直到值小于三
