我的程序有三个功能如下所示,
var userId = req.userId;
var appId = req.body.appId;
var main = 'temp/' + userId + '/templates/' + appId + '/css/main.css';
var color = req.body.color;
var font = req.body.font;
var fontSize = req.body.fontSize;
replaceThemecolor(color);
replaceFont(font);
replaceFontSize(fontSize);
function replaceThemecolor(color) {
fs.readFile(main, 'utf-8', function (err, data) {
var regex =/(\.made-easy-themeColor\s*{[^}]*color\s*:\s*)([^\n;}]+)([\s*;}])/;
var result = data.replace(regex, "$1" + color + "$3");
console.log(color);
fs.writeFile(main, result, 'utf-8', function (err) {
if (err) return console.log(err);
});
});
}
function replaceFont(font) {
fs.readFile(main, 'utf-8', function (err, data) {
var regex =/(\.made-easy-themeFont\s*{[^}]*font-family\s*:\s*)([^\n;}]+)([\s*;}])/;
var result = data.replace(regex, "$1" + font + "$3");
console.log(font);
fs.writeFile(main, result, 'utf-8', function (err) {
if (err) return console.log(err);
});
console.log(result);
})
}
function replaceFontSize(fontSize) {
fs.readFile(main, 'utf-8', function (err, data) {
var regex =/(\.made-easy-themeFontSize\s*{[^}]*font-size\s*:\s*)([^\n;}]+)([\s*;}])/;
var result1 = data.replace(regex, "$1" + fontSize + "em" + "$3");
console.log(fontSize);
fs.writeFile(main, result1, 'utf-8', function (err) {
if (err) return console.log(err);
});
});
}
在这里只有最后一个函数一直执行,当我单独执行它们时它们运行良好,但是当所有函数同时执行时会出现问题。这是fs.writeFile函数的问题吗?我想一起执行这三个功能,有没有办法做到这一点?这些功能在单独执行时效果很好。
答案 0 :(得分:1)
您的文件功能是异步的。您无法同时运行它们,因为它们会发生冲突,并且会覆盖另一个的更改。你必须运行一个,然后当它完成时,运行另一个。
或者,更好的是,只读取文件一次,处理包含所有更改的数据,然后再写一次。
如果您要按顺序运行它们,那么您需要将回调传递给完成后调用的每个函数,以便知道何时启动下一个函数。
但是,我认为更好的解决方案是传递一组替换指令,并在一次读取和写入文件时处理所有这些指令。我将为此编写一个代码示例。
这是一种在文件的一次读/写中进行所有更新的方法,并使用promises来知道操作何时完成:
function updateFile(filename, replacements) {
return new Promise(function(resolve, reject) {
fs.readFile(filename, 'utf-8', function(err, data) {
if (err) {
reject(err);
} else {
// now cycle through and do all the replacements
for (var i = 0; i < replacements.length; i++) {
data = data.replace(replacements[i].regex, replacements[i].replacer);
}
fs.writeFile(filename, data, 'utf-8', function(err) {
if (err) {
reject(err);
} else {
resolve();
}
});
}
});
});
}
updateFile(main, [{regex: /(\.made-easy-themeColor\s*{[^}]*color\s*:\s*)([^\n;}]+)([\s*;}])/, replacer: "$1" + color + "$3"},
{regex: /(\.made-easy-themeFont\s*{[^}]*font-family\s*:\s*)([^\n;}]+)([\s*;}])/, replacer: "$1" + font + "$3"},
{regex: /(\.made-easy-themeFontSize\s*{[^}]*font-size\s*:\s*)([^\n;}]+)([\s*;}])/, replacer: "$1" + fontSize + "em$3"}]).then(function() {
// update done successfully
}, function(err) {
// error
});
通过更多的工作,你可能只抽出正则表达式中的关键字,所以你只需要传递关键字,但我会把它留到另一个时间。
这是一个简化版本:
function updateFile(filename, replacements) {
return new Promise(function(resolve, reject) {
fs.readFile(filename, 'utf-8', function(err, data) {
var regex, replaceStr;
if (err) {
reject(err);
} else {
// now cycle through and do all the replacements
for (var i = 0; i < replacements.length; i++) {
regex = new Regex("(\\" + replacements[i].rule + "\\s*{[^}]*" + replacements[i].target + "\\s*:\\s*)([^\\n;}]+)([\\s*;}])");
replaceStr = "$1" + replacements[i].replacer + "$3";
data = data.replace(regex, replaceStr);
}
fs.writeFile(filename, data, 'utf-8', function(err) {
if (err) {
reject(err);
} else {
resolve();
}
});
}
});
});
}
updateFile(main, [
{rule: ".made-easy-themeColor", target: "color", replacer: color},
{rule: ".made-easy-themeFont", target: "font-family", replacer: font},
{rule: ".made-easy-themeFontSize", target: "font-size", replacer: fontSize + "em"}
], function() {
// update done successfully
}, function(err) {
// error
});
而且,如果你不想知道它什么时候完成或者能够返回错误(我不会这样做),你根本不必使用这个承诺。推荐,但代码更简单。)
function updateFile(filename, replacements) {
fs.readFile(filename, 'utf-8', function(err, data) {
var regex, replaceStr;
if (err) { return; }
// now cycle through and do all the replacements
for (var i = 0; i < replacements.length; i++) {
regex = new Regex("(\\" + replacements[i].rule + "\\s*{[^}]*" + replacements[i].target + "\\s*:\\s*)([^\\n;}]+)([\\s*;}])");
replaceStr = "$1" + replacements[i].replacer + "$3";
data = data.replace(regex, replaceStr);
}
fs.writeFile(filename, data, 'utf-8');
});
}
updateFile(main, [
{rule: ".made-easy-themeColor", target: "color", replacer: color},
{rule: ".made-easy-themeFont", target: "font-family", replacer: font},
{rule: ".made-easy-themeFontSize", target: "font-size", replacer: fontSize + "em"}
], function() {
// update done successfully
}, function(err) {
// error
});
请注意添加更多替换是多么容易。您只需在传递updateFile()
的数组中再添加一行。
答案 1 :(得分:1)
Node.js本质上是异步的。因此,您要快速连续执行三次读取操作,然后尝试写入已经锁定文件的文件,或者至少在读取文件时,不包含写入更改。我会使用更像async
的系列或瀑布方法来解决这个问题。
var async = require("async");
var userId = req.userId;
var appId = req.body.appId;
var main = 'temp/' + userId + '/templates/' + appId + '/css/main.css';
var color = req.body.color;
var font = req.body.font;
var fontSize = req.body.fontSize;
async.series({
replaceThemecolor: function(callback) {
fs.readFile(main, 'utf-8', function(err, data) {
var regex = /(\.made-easy-themeColor\s*{[^}]*color\s*:\s*)([^\n;}]+)([\s*;}])/;
var result = data.replace(regex, "$1" + color + "$3");
console.log(color);
fs.writeFile(main, result, 'utf-8', function(err) {
callback(err);
});
});
},
replaceFont: function(callback) {
fs.readFile(main, 'utf-8', function(err, data) {
var regex = /(\.made-easy-themeFont\s*{[^}]*font-family\s*:\s*)([^\n;}]+)([\s*;}])/;
var result = data.replace(regex, "$1" + font + "$3");
console.log(font);
fs.writeFile(main, result, 'utf-8', function(err) {
callback(err);
});
})
},
replaceFontSize: function(callback) {
fs.readFile(main, 'utf-8', function(err, data) {
var regex = /(\.made-easy-themeFontSize\s*{[^}]*font-size\s*:\s*)([^\n;}]+)([\s*;}])/;
var result1 = data.replace(regex, "$1" + fontSize + "em" + "$3");
console.log(fontSize);
fs.writeFile(main, result1, 'utf-8', function(err) {
callback(err);
});
});
}
}, function(err, results) {
// results is empty, but now the operation is done.
});