#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
будет выполняться асинхронно, вот в чем идея.