下面的代码打开一个文件并读取打印到控制台的内容。我把它修改为我认为会返回一个字符串,但我得到了未定义。目标不是打印内容,而是将它们保存在我可以在代码中的任何位置使用的变量中。
(我正在学习Node和JavaScript。这个问题可能之前已经被问过了;我只是不知道要把它放在哪个上下文中,这真的有助于我开发对JavaScript的理解。)
var fs = require('fs');
function sql_file(sql_file, cb) {
var fileName = "./SQLs/" + sql_file;
fs.readFile(fileName, function(err, buffer) {
if (err) return cb(err);
return cb(null, buffer.toString());
});
}
var t = sql_file('inventory.sql', function(err, contents) {
return contents.toString();
});
console.log(t);
以下是我迷路的地方:如果t
代表sql_file
的回复,那么你怎么得到undefined
?
答案 0 :(得分:1)
正如人们在评论中指出的那样,代码的问题在于您缺少异步执行的概念。如果在代码中添加一些console.log()语句,以查看每个步骤的执行时间,您将能够发现问题:
var fs = require('fs');
function sql_file(sql_file, cb) {
console.log('about to read file');
var fileName = "./SQLs/" + sql_file;
fs.readFile(fileName, function(err, buffer) {
console.log('the file has been read');
if (err) return cb(err);
return cb(null, buffer.toString());
});
console.log('call to read file made (but not finished)');
// the call to sql_file ends here and returns nothing/undefined
}
var t = sql_file('inventory.sql', function(err, contents) {
// contents will have the value when this call back is executed
// in your case this is once the file has been read.
// Keep in mind that sql_file will ALWAYS return null, though.
return contents.toString();
});
console.log(t);
如果使用这些console.log()运行代码,您将看到为什么总是未定义。一旦您的代码使用异步调用(如fs.readFile),您就不能依赖于代码的线性执行。
您应该按照以下方式编写代码,以便按预期打印值:
var fs = require('fs');
function sql_file(sql_file, cb) {
console.log('about to read file');
var fileName = "./SQLs/" + sql_file;
fs.readFile(fileName, function(err, buffer) {
console.log('the file has been read');
if (err) return cb(err);
return cb(null, buffer.toString());
});
console.log('call to read file made (but not finished)');
}
// sql_file will always return NULL but the value will
// be available to you once the callback is executed.
sql_file('inventory.sql', function(err, contents) {
console.log(contents.toString());
});
这里带走的是,一旦你已经异步,你就会全身心投入。当其中一个调用(在你的情况下为fs.readFile)是异步时,你不能指望下一行中的值可用。