Файловая система NodeJS Json для чтения и записи работает только один

#javascript #node.js #fs

#javascript #node.js #fs

Вопрос:

для школьного проекта я должен переписать объект Json с использованием node fs. Я написал модуль, и если я использую deleteCity или addCity самостоятельно, они работают совершенно нормально. Но когда я вызываю оба варианта один за другим, работает только один. В моем файле JSON есть один массив с 10 объектами. В моем основном файле javascript мне требуется мой модуль и вызываются функции addCity и deleteCity.

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

//Variablen
const citiesPath = "./cities.json";

//Funktionen
const deleteCity = (name) => {
    fs.readFile(citiesPath, "utf-8", (err, jstring) => {
        if (err) {
            console.log(err);
        }
            try {
                let data = JSON.parse(jstring);
                for (let i = 0; i < data.length; i  ) {
                    if (data[i].Name == name) {
                        data.splice(i, 1);
                    }
                }
                fs.writeFile(citiesPath, JSON.stringify(data, null, 2), (err) => {
                    if (err) {
                        console.log(err);
                    }
                });
            } catch (error) {
                console.log(error);
        }
    });
};

const addCity = (obj) => {
    fs.readFile(citiesPath, "utf-8", (err, jstring) => {
        if (err) {
            console.log(err);
        } 
            try {
                let data = JSON.parse(jstring);
                data.push(obj);
                fs.writeFile(citiesPath, JSON.stringify(data, null, 2), (err) => {
                    if (err) {
                        console.log(err);
                    }
                });
            } catch (error) {
                console.log(error);
        }
    });
};

const showCity = () => {
    fs.readFile(citiesPath, "utf-8", (err, jstring) => {
        if (err) {
            console.log(err);
        } 
            try {
                let data = JSON.parse(jstring);
                console.log(data);
            } catch (error) {
                    console.log(error);
        }
    });
};


//Exporte
module.exports = {
    deleteCity,
    addCity,
    showCity
}; 

Ответ №1:

Я полагаю, вы вызываете обе функции синхронно, т. е.

 deleteCity("London");
addCity({ "Name": "Paris" });
 

Проблема здесь в том, что оба вызова являются асинхронными, а второй начнется до завершения первого вызова, то есть в основном до удаления города.

Если это школьный проект, самым простым решением для исправления вашего кода является использование синхронной версии fs вызовов fs.readFileSync и fs.writeFileSync :

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

//Variablen
const citiesPath = "./cities.json";

//Funktionen
const deleteCity = (name) => {
    const jstring = fs.readFileSync(citiesPath, "utf-8");
    let data = JSON.parse(jstring);
    for (let i = 0; i < data.length; i  ) {
        if (data[i].Name == name) {
            data.splice(i, 1);
        }
    }
    fs.writeFileSync(citiesPath, JSON.stringify(data, null, 2));
};

const addCity = (obj) => {
    const jstring = fs.readFileSync(citiesPath, "utf-8");
    let data = JSON.parse(jstring);
    data.push(obj);
    fs.writeFileSync(citiesPath, JSON.stringify(data, null, 2));
};

const showCity = () => {
    const jstring = fs.readFileSync(citiesPath, "utf-8");
    let data = JSON.parse(jstring);
    console.log(data);
};


//Exporte
module.exports = {
    deleteCity,
    addCity,
    showCity
};
 

Обратите внимание, что вам не нужно перехватывать ошибки только для их регистрации в ваших синхронных функциях. Если ошибка выдана и не перехвачена, Node.js будет регистрировать его для вашего.

Комментарии:

1. Это сработало, спасибо! Каким было бы решение, если бы я хотел сделать это асинхронно? Я читал на некоторых сайтах, что люди предпочитают асинхронную версию.

2. @Deonisos Да, асинхронный код предпочтительнее, потому что он не блокирует другие задачи. fs.writeFile ожидает функцию обратного вызова в качестве третьего параметра. В функции deleteCity , внутри обратного fs.writeFile вызова, если вы вызовете addCity там, то addCity будет выполняться асинхронно, вот в чем идея.