用Node.js,如何让用户确认覆盖文件?

我有一个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); 

这会失败:程序不会等待用户input并存在。

注:您需要运行两次以查看失败。 第一次,它创build的文件罚款。

我应该如何继续?

由于writeData正在调用一些asynchronous函数(readline),因此它需要提供一个callback函数(您将调用传递给函数,并在文件更新之后调用回来)。为了清楚起见,writeData函数仍然是同步的,因为您调用了xxxSync方法(你不是通过添加callback使它同步),但readline是asynchronous的。所以你的函数必须等到readline完成。callback是继续的信号,这就是为什么下一个console.writeline是在callback。

否则,console.log将在readline完成writeData之前运行:

 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"); }); 

签出async.js来帮助展开一些嵌套的callback地狱。

使您的writeDataasynchronous。 这与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)}); });