2017-02-22 91 views
-1

我最近開始學習MEAN。我有以下代碼返回MongoDb的文檔集合。如何在node.js中從異步函數返回值

var giveData = function() 
{ 
var mongodb = require('mongodb'); 
var mongoClient = mongodb.MongoClient; 

var url = 'mongodb://127.0.0.1:27017/ngs' 



var retVal; // this is a return value which will contain documents 


mongoClient.connect(url, function(err, db) 
         { 
          if (err) 
          { 
           console.log(err) 
          }else 
          { 
           db.collection('employees').find().toArray(
            function(err, doc) 
            { 
             if(err) 
             { 
              throw err; 
             }else{ 
              console.log(doc); // this works fine 
              retVal = doc;  // this does not assign the value ???? why so ?? 

             } 

            } 

           ); 

          } 
         } 
        ) 

console.log("Message from lib");      
console.log(retVal); // this returns undefined 
console.log("-----------------"); 

return retVal; // this may return data from the server but is returning undefined 


} 

module.exports ={ showMessage: showMessage, 
         giveData: giveData 
        } 

從言論很明顯,我想從MongoDB的數據庫文件收集到一個名爲retVal的變量,這是我在分配正確的流程文檔的價值。

儘管文檔已成功顯示,但不知何故,它並未分配給名爲retVal的變量。

請扔一些輕的主題所以文檔集合從()稱爲giveData功能

感謝和問候返回。

+0

你...不知道。 :) –

回答

0

在本節

var retVal; // this is a return value which will contain documents 

retVal是不確定的

,並在底部

return retVal; // this may return data from the server but is returning undefined 

retVal仍然是不確定的,因爲調用mongoClient.connect是異步

您在特定時刻返回retVal。這個值不會改變。

您應該將回調函數傳遞給giveData,以便您可以在收到返回的數據後訪問它。

var giveData = function(callback) { 
    var mongodb = require('mongodb'); 
    var mongoClient = mongodb.MongoClient; 

    var url = 'mongodb://127.0.0.1:27017/ngs' 

    mongoClient.connect(url, function(err, db) { 
    if (err) { 
     callback(err) 
    } else { 
     db.collection('employees').find().toArray(function(err, doc) { 
     if(err) { 
      callback(err) 
     } else { 
      callback(null, doc) 
     } 
     }) 
    }  
    } 

} 

module.exports = { 
    showMessage: showMessage, 
    giveData: giveData 
} 

而不是用它像這樣

giveData(function(err, doc) { 
    if(err) { 
    // handle error 
    } else { 
    // you can now use doc! 
    } 
}) 
+0

您的回覆給予了很好的關注。你可以對回調(err)和callBack(null,doc)進行一些介紹嗎?我認爲這將會幫助我理解異步NodeJs。謝謝。 –

+0

這是處理回調的節點約定。你在'mongoClient.connect'中自己使用它。基本上這個想法是,第一個參數總是錯誤,這是你應該檢查的第一件事。如果一切順利並且沒有錯誤,則發送null以指定沒有錯誤,因此'callback(null,doc)'。 –

+0

謝謝Yoni Levy。但是如果沒有錯誤,我仍然無法理解如何從giveData()返回值。基本上,我想要的是我想從應該包含來自MongoDb的數據的函數返回一個值。 –

0

您需要更熟悉Node.js的異步流程 - this may help, for example

你的底console.log和回報發生以前您的分配(retVal = doc;

mongoClient的所有功能都是異步的,並返回分配後應該發生的權利(發生後收集employees被取出)。

該代碼繼續到您當前的return而無需等待db.collection('employees')的數據。

所有代碼都可以重構爲使用node.js回調。當然有很多優雅的方法來解決它,但只是爲了向你展示一個例子。

var retVal; 
    function getEmployees(cb) { 
     return mongoClient.connect(url, function(err, db) { 
      if (err) return cb(err); 
      db.collection('employees').find().toArray(
       function(err, doc){ 
        if(err) return cb(err); 
        console.log(doc); 
        cb(null,doc); 
        }); 
      }); 
     } 

getEmployees((err, result) => { 
     if (err) console.log('Error:',err); 
     retVal = result; 
     return retVal; 
}); 
相關問題