如果我从一个文件中读取一个JSON数组,那么我就会得到一个旧的未更改的数组

时间:2018-04-02 20:46:55

标签: javascript arrays json node.js

我正在阅读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"}]

2 个答案:

答案 0 :(得分:3)

您的代码存在两个主要问题。第一个是save是一个异步函数。这意味着你在它之后直接编写的任何代码都会在它完成之前运行。在这方面,它就像setTimeout一样。

console.log(1);
setTimeout(function() {
  console.log(2);
}, 100);
console.log(3);

注意它在3之前如何输出2。这是因为setTimeoutfs.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)

requirecache该文件。而不是要求,使用fs.readFileSync方法再次读取文件。

json = fs.readFileSync(file);

另外,正如@MikeC指出的那样,您要异步写入文件,因此要么将其切换为同步版本writeFileSync,要么使用readFile和{重写代码{1}}并使用回调。