2017-02-11 70 views
0

我仍然是NodeJS的n00b,所以这个问题可能有点基本。NodeJS + MongoJS:嵌套回调问题

我正在使用MongoJS来读取两个逻辑上相关的集合。第一个find()返回一个值,我传递给第二个find()以获取我需要的信息。

我试过几种策略,最后一个(片段#1)是我导出的类。

在此之前,我只是有一个函数做了返回,返回所需的值,即“config [0]”。

在这段代码中,我所做的只是将“sapConfig”属性设置为单词“test”,但是当我执行此代码时,在调用“get_config()”后,“sapConfig”的值始终为“null”方法和 - 最奇怪的 - 对“this.sapConfig ='test'”的引用会产生一个错误,即“无法设置未定义的属性'sapConfig'”。

当我的代码只是一个简单的函数,返回语句(代码段#2),没有错误产生,但返回值总是“未定义”,尽管console.log()语句显示被返回的变量的值具有期望的值。是什么赋予了?

代码段#1:返回Object

"use strict"; 

var mongojs = require('mongojs'); // MongoDB API wrapper 

module.exports = function(regKey) { 

    this.regKey = regKey; 
    this.sapConfig = null; 

    this.get_config = function() { 

     // Read SAP connection information from our MONGO db 
     var db = mongojs('mongodb://localhost/MIM', ['Configurations','Registrations']); 

     db.Registrations.find({ key: this.regKey }, function(err1, registration){ 
      console.log('Reg.find()'); 
      console.log(registration[0]); 
      db.Configurations.find({ type: registration[0].type }, function(err2, config){ 
       console.log('Config.find()'); 
       console.log('config=' + config[0].user); 
       this.sapConfig = 'test'; 
      }); 
     }); 
    } 

    this.get_result = function() { 
     return this.sapConfig; 
    } 
} 

再次,在片段#1中的代码,当我提出 “)get_config(” 调用,导致一个错误,当它执行线“this.sapConfig ='test'”。

但是,在发生此错误后,我可以执行“obj.get_result()”,并获取它初始化的值,即null。换句话说,同样的代码不会产生一个错误说,“这”是不明确的。在“get_config()”方法

代码片段#2:使用“return”语句

"use strict"; 

var mongojs = require('mongojs'); // MongoDB API wrapper 

module.exports = function(regKey) { 

     // Read SAP connection information from our MONGO db 
     var db = mongojs('mongodb://localhost/MIM', ['Configurations','Registrations']); 

     db.Registrations.find({ key: regKey }, function(err1, registration){ 
      console.log('Reg.find()'); 
      console.log(registration[0]); 
      db.Configurations.find({ type: registration[0].type }, function(err2, config){ 
       console.log('Config.find()'); 
       console.log('config=' + config[0].user); 
       return config[0].user; 
      }); 
     }); 
} 

当我收到返回值并检查它时,它是“未定义的”。例如,在节点CL我发出以下命令:

var config = require('./config') // The name of the module above 
> var k = config('2eac44bc-232d-4667-bd24-18e71879f18c') 
undefined <-- this is from MongoJS; it's fine 
> Reg.find() <-- debug statement in my function 
{ _id: 589e2bf64b0e89f233da8fbb, 
    key: '2eac44bc-232d-4667-bd24-18e71879f18c', 
    type: 'TEST' } 
Config.find() 
config=MST0025 
> k <-- this should have the value of "config[0]" 
undefined 

你可以看到,查询是成功的,但“K”的值为“undefined”。这里发生了什么?

我不在乎我使用哪种方法,我只需要其中一个工作。

在此先感谢!

+0

在我的第二部分回答中看到我的新例子:)干杯。 – matt

回答

0

this.sapConfig无法访问。那是因为this是指在当前函数内。我喜欢todo,有一个变量,指的是你知道sapConfig位于的功能实例。

例:

function Foo() { 
    var self = this; 

    this.test = "I am test"; 

    var bar = function(){ 
    return function(){ 
     console.log(this.test); //outputs undefined (because this refers to the current function scope) 
     console.log(self.test); //outputs "I am test"; 
    } 
    } 
} 

这里是我的例子你的第一个代码片段来实现:

"use strict"; 

var mongojs = require('mongojs'); // MongoDB API wrapper 

module.exports = function(regKey) { 
    var self = this; 

    this.regKey = regKey; 
    this.sapConfig = null; 

    this.get_config = function() { 

    // Read SAP connection information from our MONGO db 
    var db = mongojs('mongodb://localhost/MIM', ['Configurations', 'Registrations']); 

    db.Registrations.find({ key: this.regKey }, function(err1, registration) { 
     console.log('Reg.find()'); 
     console.log(registration[0]); 
     db.Configurations.find({ type: registration[0].type }, function(err2, config) { 
     console.log('Config.find()'); 
     console.log('config=' + config[0].user); 
     self.sapConfig = 'test'; 
     }); 
    }); 
    } 

    this.get_result = function() { 
    return self.sapConfig; 
    } 
} 

对于你的第二个片段。您试图从嵌套回调中返回一个值。由于嵌套函数是异步的,所以你不能这样做。

这里是我想从嵌套回调返回值:

练习2:

//Function example 
var functionWithNested = function(done) { 
    //Notice the done param. 
    // It is going to be a function that takes the finished data once all our nested functions are done. 

    function() { 
    //Do things 
    function() { 
     //do more things 
     done("resultHere"); //finished. pass back the result. 
    }();//end of 2nd nested function 
    }(); //end of 1st nested function 
}; 

//Calling the function 
functionWithNested(function(result) { 
    //Callback 
    console.log(result); //resultHere 
}) 

下面是使用例子代码:

"use strict"; 

var mongojs = require('mongojs'); // MongoDB API wrapper 

module.exports = function(regKey, done) { 

    // Read SAP connection information from our MONGO db 
    var db = mongojs('mongodb://localhost/MIM', ['Configurations', 'Registrations']); 

    db.Registrations.find({ key: regKey }, function(err1, registration) { 
    console.log('Reg.find()'); 
    console.log(registration[0]); 
    db.Configurations.find({ type: registration[0].type }, function(err2, config) { 
     console.log('Config.find()'); 
     console.log('config=' + config[0].user); 
     done(config[0].user); 
    }); 
    }); 
} 

//Then wherever you call the above function use this format 
// if config is the name of the function export above... 

new Config().(regKey, function(result){ 

    console.log(result); //config[0].user value 
}) 

很多很多的代码,但我希望你能够遵循它。如果您还有其他问题,请告诉我!干杯。

+0

非常好!像魅力一样工作,现在你已经解释了它,这非常有意义。你知道为什么其他代码片段返回“未定义”,即为什么** return **语句没有按预期工作? – Ishmael

+0

很高兴它对你有意义。对于你的return语句问题:你不能从嵌套的回调中返回一个值。我添加另一个我喜欢从嵌套回调中返回值的例子。只是给我几个:) – matt

+0

是的!完善!这是完全合理的。我不是在“异步”思考。优秀的信息。非常感谢! – Ishmael