这是我正在尝试做的事情。
var data = data.replace(/{{(.*?)}}/g, function (a, b) {
if (fs.existsSync("./include" + b)) {
return new String(fs.readFileSync('./include' + b));
} else {
console.log("ERROR!: ./include" + a + " not found.");
return "";
}
});
代码完美无缺。但是,existsSync和readFileSync将阻止节点进程。
我无法在手前缓冲所有文件,因为它太大并且消耗大量内存。
我正在看诺言,但不是.then()会阻止线程吗?
在这种情况下有没有办法使用fs.readFile?
答案 0 :(得分:0)
您可能想要使用readFile
代替,也可以使用错误返回检查文件是否存在
data.replace(/{{(.*?)}}/g, function (a, b) {
fs.readFile('./include' + b, (err, fileData) => {
if (err) {
console.log(err);
return;
}
data = new String(fileData)
})
});
答案 1 :(得分:0)
您可以选择exist()
和readFile
的异步功能。但是,exist
是deprecated。建议改用access或stat。
var data = data.replace(/{{(.*?)}}/g, function (a, b) {
fs.access("./include" + b, function(err) {
if (err) {
// specific "no such file or directory" error code
if (err.code === 'ENOENT')
return console.log("ERROR!: ./include" + a + " not found.");
// throw another error as well
throw err;
}
fs.readFile('./include' + b, "utf-8", function(err, data) {
if (err)
// handle error
return data;
});
});
});
但是,如上所述,也不建议这样做。
使用fs.access()检查之前文件的可访问性 不建议调用fs.open(),fs.readFile()或fs.writeFile()。 这样做会引入竞争条件,因为其他过程可能会发生变化 两个调用之间的文件状态。相反,用户代码应该 直接打开/读/写文件并处理引发的错误 文件无法访问。
作为建议,我们的代码可以修改为:
var data = data.replace(/{{(.*?)}}/g, function (a, b) {
fs.readFile('./include' + b, "utf-8", function(err, data) {
if (err) {
if (err.code === 'ENOENT')
return console.log("ERROR!: ./include" + a + " not found.");
throw err;
}
return data;
});
});
答案 2 :(得分:0)
我建议不要在单个功能中尝试这样做。细分你需要做的事情,特别是涉及异步时。
const fs = require('fs');
// find a list of unique file references
function findFiles (data) {
const files = {};
const regex = /{{(.*?)}}/g;
while ((match = regex.exec(data)) != null) {
files[match[1]] = true;
}
return Object.keys(files);
}
function replaceFile (data, filePath) {
return new Promise((resolve, reject) => {
fs.readFile(`./include${filePath}`, function (err, fileData) {
if (err) {
console.log(err);
return resolve(data);
}
// we can replace multiple file references without reading
// the file multiple times.
const regex = new RegExp('{{' + filePath + '}}', 'g');
return resolve(data.replace(regex, fileData));
});
});
}
// use of reduce to allow us to chain the promises so we modify
// data one file at a time and don't rely on it bing a reference
// which we're modifying.
function replaceFiles (data, filePaths) {
return filePaths.reduce(
(promise, filePath) => {
return promise.then((newData) => {
return replaceFile(newData, filePath);
});
},
Promise.resolve(data)
);
}
const data = 'hello {{/file.txt}} {{/file2.txt}} {{/file.txt}} world';
const filePaths = findFiles(data);
console.log({ filePaths });
replaceFiles(data, filePaths)
.then(data => console.log({ data }));