我在Javascript / Node.js中有一个命令行程序,可以将数据写入文件。
我想要求用户确认覆盖文件(如果文件已存在)。
这失败了:
function writeData (filename, data) {
var fs = require ('fs');
try {
fs.writeFileSync(filename, data, {flag: 'wx'});
} catch (e) {
if (e.code === "EEXIST") {
console.error ("File already exists.");
var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);
rl.question("Overwrite? [yes]/no: ", function(answer) {
if(answer == "no") {
console.log ("Not overwritting, bye.");
process.exit (1);
}
else {
console.log ("Overwriting file.");
try {
fs.writeFileSync(filename, data, {flag: 'w'});
} catch (ee) { throw ee; }
rl.close();
}
});//question()
}
else { throw e; }
}//catch(e)
}
writeData ("/tmp/foo", "foo bar");
console.log ("do something else");
writeData ("/tmp/bar", "bar baz");
console.log ("done.");
process.exit(0);
失败:程序不等待用户输入并且存在。
注意:您需要运行两次以查看失败。 第一次,它创建文件很好。
我该怎么办?
答案 0 :(得分:1)
由于writeData正在调用一些异步函数(readline),它需要提供一个回调(在调用函数时传递给它,在文件更新之后,你回调。要清楚,writeData仍然是同步的,因为你'重新调用xxxSync方法(并且你没有通过添加回调使它同步)但readline是异步的。所以你的函数必须等到readline完成。回调是继续的信号,这就是为什么下一个console.writeline是在回调中。
否则,console.log将在writeData完成readline之前运行:
writeData ("/tmp/foo", "foo bar");
console.log ("do something else");
您需要执行以下操作:
function writeData (filename, data, fn) {
...
rl.question("Overwrite? [yes]/no: ", function(answer) {
if (answer === 'yes) {
// do work
fn(null); // null is err
return;
然后在电话中:
writeData ("/tmp/foo", "foo bar", function(err) {
if (err) {
// handle, return,
}
console.log ("do something else");
});
Checkout async.js to help展开一些嵌套的回调地狱。
答案 1 :(得分:0)
让writeData
异步。这更符合node.js范例:
var fs = require('fs');
var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);
function writeData (filename, data, done){
fs.writeFile(filename, data, {flag: "wx"}, function (err) {
if (err){
if(err.code == "EEXIST"){
console.error("File " + filename + "already exists.");
rl.question("Overwrite? [yes]/no: ", function(answer) {
if(answer === "no") {
console.log ("Not overwritting " + filename);
} else {
console.log ("Overwriting " + filename);
fs.writeFile(filename, data, done);
}
});
} else {
if(done) done(err);
}
}
else if(done) done(null);
});
}
writeData ("/tmp/foo", "foo bar", function(err){
if(err) throw err;
writeData ("/tmp/bar", "bar baz", function(){process.exit(0)});
});