Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将值指定给对象时,未定义从何而来?_Javascript_Node.js - Fatal编程技术网

Javascript 将值指定给对象时,未定义从何而来?

Javascript 将值指定给对象时,未定义从何而来?,javascript,node.js,Javascript,Node.js,下面的代码打开一个文件并读取将其打印到控制台的内容。我将其修改为我认为会返回字符串的内容,但未定义。目标不是打印内容,而是将它们保存在一个变量中,我可以在代码的任何地方使用它 我正在学习Node和JavaScript。这个问题以前可能有人问过;我只是不知道应该把它放在什么上下文中,这将真正帮助我理解JavaScript var fs = require('fs'); function sql_file(sql_file, cb) { var fileName = "./SQLs/" +

下面的代码打开一个文件并读取将其打印到控制台的内容。我将其修改为我认为会返回字符串的内容,但未定义。目标不是打印内容,而是将它们保存在一个变量中,我可以在代码的任何地方使用它

我正在学习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_文件的返回,那么为什么会得到未定义?

正如人们在评论中所指出的,您的代码的问题在于缺少异步执行的概念。如果在代码中添加几个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为asynch时,您不能期望下一行中的值可用。

查找asynchronous.Kris Kowal to the rescue、Google async nodejs library或promises Patterns您无法在回调中返回值,因为它是异步调用的。我认为OP应该在使用任何新库之前了解发生了什么@DistROy的链接是一个很好的基础。哇,Hector,我真的能理解这里发生了什么,它是因为我过去10年所知道的都是VB。有些VB概念适用,但很少。我认为异步是我在思考问题时遇到的问题。是的,异步概念需要一点时间才能理解,它与VB、C、Java或Ruby完全不同。Hector,这就是为什么我要问如何将文件内容放入字符串中。我有一个oracle get,var reader=connection.readerSELECT*来自库存[];我需要一次写入并在任何地方运行,所以var reader=connection.readersql_文件'Inventory.sql',[];。我不是在找人来做我的家庭作业,只是为了更好地理解。如果connection.reader是异步的,并且很可能是异步的,那么您不能将它放在字符串中,并期望在下一行中使用它。您需要在回调中指定字符串,就像在示例中的sql\u文件回调中一样。您需要将一些代码移动到回调中,这就是为什么人们谈论末日金字塔的原因,因为所有东西都开始嵌套。当你采用这种方法时,人们在评论中提到的图书馆和想法将变得更有意义。但你可能需要先感受痛苦,然后再尝试。赫克托,我也按我需要的方式工作,你是这个论坛的真正资产。。。