我正在阅读require
来自文件的JSON对象。我可以正确地读取JSON,但在我向其添加数据并将其保存到文件中之后,重新要求不会获取更新的JSON,而是检索旧文件。有人可以解释为什么会这样吗?我该如何解决这个问题?
var file = process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'] + "\\AppData\\Roaming\\BetterDiscord\\plugins\\Test.json";
var json = require(file);
console.log(JSON.stringify(json.img));
json.img.push({name:"Test"});
console.log(JSON.stringify(json.img));
save(JSON.stringify(json), file);
json = require(file);
console.log(JSON.stringify(json.img));
这是save
方法:
var save = function(value, file){
var fs = require('fs');
fs.writeFile(file, value, function(err) {
if (err) {
console.log(err);
}
});
};
这是输出:
Output 1: [{"name":"A"},{"name":"B"}]
Output 2: [{"name":"A"},{"name":"B"}, {"name":"Test"}]
Output 3: [{"name":"A"},{"name":"B"}]
答案 0 :(得分:3)
您的代码存在两个主要问题。第一个是save
是一个异步函数。这意味着你在它之后直接编写的任何代码都会在它完成之前运行。在这方面,它就像setTimeout
一样。
console.log(1);
setTimeout(function() {
console.log(2);
}, 100);
console.log(3);
注意它在3
之前如何输出2
。这是因为setTimeout
与fs.writeFile
一样,是异步的。为确保在完成后运行代码,您可以传递回调或使用Promises(在此问题范围之外但非常有用)。所以你的代码可能看起来像这样。
const save = (path, cb) => {
setTimeout(() => {
cb();
}, 100);
};
let path = 'path/to/file';
save(path, () => {
console.log(`Saved ${path}`);
});
console.log(`Saving ${path}...`);
使用sync
的{{1}}版本也可以避免这一切。
writeFile
下一个问题源于fs.writeFileSync(file, value);
缓存结果的方式。这样做是因为它用于加载模块,并且大多数时候它们不会动态变化。而是直接从系统加载文件。这也可以异步或同步使用。以下是我使用同步代码重写代码的方法(尽管异步通常更可取)。
require
答案 1 :(得分:1)
require
将cache该文件。而不是要求,使用fs.readFileSync
方法再次读取文件。
json = fs.readFileSync(file);
另外,正如@MikeC指出的那样,您要异步写入文件,因此要么将其切换为同步版本writeFileSync
,要么使用readFile
和{重写代码{1}}并使用回调。