2017-02-11 53 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