写入 json 文件时,写入并未完全覆盖之前的数据

When writing to a json file, the writing isn't fully overwriting the previous data

我正在尝试从 JSON 文件中获取一些数据,更改该数据并用新的和更改后的数据覆盖原始文件的数据,但是在写回文件时,一些旧数据是被抛在后面。

我的读取、修改、写入文件的js代码如下:

const fs = require("fs/promises");

const timeSelectForm = document.getElementById('timeSelectForm');
const textInput = document.getElementById('timeSelectInput');

const activitiesList = document.getElementById('activitiesList');
const addActivity = document.getElementById('addActivity');
let addActivityForm;
let addActivityTextInput;

async function onStart() {
    let saveData;
            
            try {
                await fs.access("./save.json"); // check if the the file exists
            } catch {
                saveData = { selectedTime: "", activityList: [], selectedActivity: "" }; // give saveData default values if the file doesnt exist
            }
        
            if (!saveData) {
                saveData = JSON.parse(await fs.readFile("./save.json", "utf8")); // if the file exists then read the contents of the file and save it to saveData
            }
        
            let activities = saveData.activityList;

            activities.forEach(activity => {
                activitiesList.innerHTML = /*html*/`<li>${activity}</li>` + activitiesList.innerHTML;
            });


            if (saveData.activityList.length == 6) {
                document.getElementById("addActivity").remove();
            }
}


// when timeSelectForm is submitted call async function
timeSelectForm.addEventListener('submit', async function (e) {
    e.preventDefault(); // prevent default page refresh

    let saveData;

    try {
        await fs.access("./save.json"); // check if the the file exists
    } catch {
        saveData = { selectedTime: "", activityList: [], selectedActivity: "" }; // give saveData default values if the file doesnt exist
    }

    if (!saveData) {
        saveData = JSON.parse(await fs.readFile("./save.json", "utf8")); // if the file exists then read the contents of the file and save it to saveData
    }

    let timeInput = textInput.value === '' ? "00:10:00" : textInput.value; // if time input is empty then set time input to 10mins otherwise set time input to textInput.value
    
    saveData.selectedTime = timeInput;

    await fs.writeFile("./save.json", JSON.stringify(saveData, null, 2), 'utf8'); // save data to JSON file

    textInput.value = ''; // clear the text input
});

let addActivityHasClicked = false;

document.body.addEventListener('click', async function (event) {
    if (!addActivityHasClicked && event.target.id == "addActivity") {
        addActivityHasClicked = true;
        event.target.innerHTML = /*html*/`
        <form id="addActivityForm">
            <input type="textInput" id="addActivityInput" placeholder="Activity">
        </form>`; // clear the inner html and put in the form
        addActivityForm = document.getElementById('addActivityForm');
        addActivityInput = document.getElementById('addActivityInput');

        addActivityForm.addEventListener('submit', async function (e) {
            e.preventDefault(); // prevent default page refresh
        
            let saveData;
            
            try {
                await fs.access("./save.json"); // check if the the file exists
            } catch {
                saveData = { selectedTime: "", activityList: [], selectedActivity: "" }; // give saveData default values if the file doesnt exist
            }
        
            if (!saveData) {
                saveData = JSON.parse(await fs.readFile("./save.json", "utf8")); // if the file exists then read the contents of the file and save it to saveData
            }
        
            let activity = addActivityInput.value;

            saveData.activityList.push(activity);
        
            await fs.writeFile("./save.json", JSON.stringify(saveData, null, 2), 'utf8'); // save data to JSON file
        
            if (saveData.activityList.length >= 6) {
                event.target.remove();
            } else {
                event.target.innerHTML = "+"; // clear the inner html and put in the +
                activitiesList.innerHTML = /*html*/`<li>${activity}</li>` + activitiesList.innerHTML
            }
            
            addActivityHasClicked = false;
        });
    }
});

document.body.addEventListener("click", async function (e) {
    if (e.target.tagName == "LI" && e.target.id != "addActivity") {
        hasBeenSelected = true;
        let saveData;
            
        try {
            await fs.access("./save.json"); // check if the the file exists
        } catch {
            saveData = { selectedTime: "", activityList: [], selectedActivity: "" }; // give saveData default values if the file doesnt exist
        }
    
        if (!saveData) {
            saveData = JSON.parse(await fs.readFile("./save.json", "utf8")); // if the file exists then read the contents of the file and save it to saveData
        }

        saveData.selectedActivity = e.target.innerHTML;


        await fs.writeFile("./save.json", JSON.stringify(saveData, null, 2), 'utf8'); // save data to JSON file
        
        const activeElm = document.getElementById("active");
        if (activeElm) {
            activeElm.removeAttribute("id");
        }
        e.target.setAttribute("id","active");
    }
});

document.body.addEventListener("click", async function (e) {
    if (e.target.id == "active") {
        let saveData;
            
        try {
            await fs.access("./save.json"); // check if the the file exists
        } catch {
            saveData = { selectedTime: "", activityList: [], selectedActivity: "" }; // give saveData default values if the file doesnt exist
        }
    
        if (!saveData) {
            saveData = JSON.parse(await fs.readFile("./save.json", "utf8")); // if the file exists then read the contents of the file and save it to saveData
            console.log(saveData);
        }

        saveData.selectedActivity = "null";
        const index = saveData.activityList.indexOf(e.target.innerHTML);
        saveData.activityList.splice(index, 1);
        e.target.remove();

        await fs.writeFile("./save.json", JSON.stringify(saveData, null, 2), 'utf8'); // save data to JSON file

        location.reload();
    }
});

onStart();

我正在使用带有此 HTML 代码的电子:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Hello World!</title>
    <link rel="stylesheet" href="./home.css">
</head>

<body>
    <div class="wrapper">
        <div class="time-select" id="timeSelect">
            <form id="timeSelectForm">
                <input id="timeSelectInput" type="text" pattern="\d\d:\d\d:\d\d" placeholder="00:10:00"
                    oninput="this.value = this.value.replace(/[^0-9.]/g, ':').replace(/(\..*?)\..*/g, '');" />
            </form>
        </div>

        <div class="activity-select">
            <ul id="activitiesList">
                <li id="addActivity">
                    +
                </li>
            </ul>
        </div>
    </div>

    <script src="./home.js"></script>
</body>

</html>

当我单击 div 时调用此代码,它旨在从屏幕和 JSON 文件中删除 div。 (e.target是我点击的div)

在 运行 此代码并单击 div 之后,我的 JSON 文件最终看起来像这样:

{
  "selectedTime": "12:34:56",
  "activityList": [
    "test5",
    "test6"
  ],
  "selectedActivity": "test4"
}y": "test4"
}

编辑:(更多信息)我已经测试过将新数据保存到另一个文件,该文件工作正常并且不会引起任何问题。我还在文本编辑器和控制台中阅读了该文件,但都给出了同样混乱的结果。

编辑 2:经过进一步测试,我发现我的 js 文件中的其他地方干扰了对 JSON 文件的保存,导致生成的文件变得一团糟。我现在已经将完整的代码添加到我的文件中,但我不确定问题出在哪里以及如何防止它们。任何关于此的指示将不胜感激,谢谢! 此外,我使用的是 electron,这意味着我可以在纯 js 代码中使用 Node.js fsPromises,因此在测试我的代码时请注意这一点。谢谢!

经过大量测试,我发现当我检查对任何 LI 元素的点击时,即在删除函数写入的同时读取 JSON JSON 这会导致 JSON 文件混乱。

简而言之,在读取和写入 JSON 文件时,请确保您没有同时执行这两项操作,为了排除故障,我在每次读取和写入后添加了 console.log 语句并看到它正在发送重叠的请求,导致混乱的结果 JSON 文件。

if (!saveData) {
    saveData = JSON.parse(await fs.readFile("./save.json", "utf8")); // if the file exists then read the contents of the file and save it to saveData
    console.log(saveData);
}

您正在覆盖上一行中的 saveData 值

saveData = { selectedTime: "", activityList: [], selectedActivity: "" }; // give saveData default values if the file doesnt exist

如果您删除上面的行,您的代码应该可以工作