2017-01-15 92 views
2

我知道Node.js的非阻塞I/O和什麼是異步函數,但我很難指出爲什麼代碼運行起來就像它運行。JavaScript代碼不能按照想要的順序運行(Node.js,MongoDB)

我連接到一個MongoDB集合,搜索重複項,把第一個值在數組對象中重複(dupIndex)。 (console.log(dupIndex);),但當我以後使用.length屬性時爲0(console.log(dupIndex.length);) - 當我是數組打印時實際上期待2.

我想繼續和操縱與我在dupIndex(如使用deleteMany方法)的數據收集,如果它顯示0,我不能,至少不喜歡這個。有人可以解釋這一點,並幫助我嗎?

謝謝!

//connect us to a running MongoDB server 
const {MongoClient, ObjectID} = require('mongodb'); 

var dataBase = "TodoApp"; 
//connecting to a database 
//connects to the database /TodoApp, if no such db exists it auto creates it 
MongoClient.connect(`mongodb://localhost:27017/${dataBase}`, (err, db)=>{ 
    if(err){ 
     //return or 'else' - so if an error happens, it won't continue 
     return console.log(`Unable to connect. Error: ${err}`); 
    } 

    console.log(`Connected to MongoDB server. Database: ${dataBase}.`); 
     var dupIndex = []; 
    //find all 
    db.collection('Todos') 
    .find() 
    .toArray().then((docs) => { 
     for (var i =0; i< docs.length -1; i++){ 
      for(var j =i+1; j< docs.length; j++){ 
        if(docs[i].text === docs[j].text) 
        { 
         console.log(`in`); 
         dupIndex.push(docs[i].text); 
         i++; 
        } 
      } 
     } 
     console.log(dupIndex); 

    }, (err)=> { 
     console.log(`unable t o fetch`); 
    }); 

    console.log(dupIndex.length); 
    // for(var i = 0; dupIndex) 
    //close the connection to the db 
    db.close(); 
}); 

回答

2

由於執行console.log(dupIndex.length);在嵌套循環之前運行。

db.collection('Todos') 
.find() 
.toArray() 

這是一個異步調用,控制傳遞給console.log(dupIndex.length); 嘗試編寫console.log(dupIndex.length);在console.log旁邊(dupIndex);

例如:

db.collection('Todos') 
.find() 
.toArray().then((docs) => { 
    for (var i =0; i< docs.length -1; i++){ 
     for(var j =i+1; j< docs.length; j++){ 
       if(docs[i].text === docs[j].text) 
       { 
        dupIndex.push(docs[i].text); 
        i++; 
       } 
     } 
    } 
    return dupIndex; 
}, (dupIndexRecieved)=> { 
    console.log(dupIndexRecieved.length); data recieved here 
}, (err)=> { 
    console.log(`unable t o fetch`); 
}); 
+0

感謝您的答覆!是的,據我瞭解,但非常模糊。 你能解釋爲什麼它發生在這裏嗎?我通常如何避免這種情況/將來使用它? – Defaceo

+0

db.collection(「託多斯」) .find() .toArray() 此功能異步所以當這個函數被調用的node.js事件循環發送請求到MongoDB的數據,同時當請求被受理的MongoDB eventloop將控件傳遞給console.log(dupIndex.length)的下一段代碼;在你的情況下,當從mongo收到響應時,你的代碼被觸發並填充你的數組。 –

+0

嘗試使用承諾更好,並通過鏈接結果 例如: –

0

//連接我們到正在運行的MongoDB服務器

const {MongoClient, ObjectID} = require('mongodb'); 

var dataBase = "TodoApp"; 
//connecting to a database 
//connects to the database /TodoApp, if no such db exists it auto creates it 
MongoClient.connect(`mongodb://localhost:27017/${dataBase}`, (err, db)=>{ 
if(err){ 
    //return or 'else' - so if an error happens, it won't continue 
    return console.log(`Unable to connect. Error: ${err}`); 
} 

console.log(`Connected to MongoDB server. Database: ${dataBase}.`); 
    var dupIndex = []; 
//find all 
db.collection('Todos') 
.find() 
.toArray().then((docs) => { 
    for (var i =0; i< docs.length -1; i++){ 
     for(var j =i+1; j< docs.length; j++){ 
       if(docs[i].text === docs[j].text) 
       { 
        console.log(`in`); 
        dupIndex.push(docs[i].text); 
        i++; 
       } 
     } 
    } 

    //Mongo db find returns a promise. The value you are accessing with the then function. So whatever you want to do with the db query return value you have to do it here inside the then function. 

    console.log(dupIndex.length); 

    console.log(dupIndex); 
    // for(var i = 0; dupIndex) 
    //close the connection to the db 
    db.close(); 

}, (err)=> { 
    console.log(`unable t o fetch`); 
}); 

//when you make the call here its get called before the then function. Thats why the length is zero. 

}); 
+0

感謝您的答覆!爲什麼它在函數之前被調用? :s – Defaceo

+1

因爲那是一個異步函數。當你調用一個異步函數時,它不會阻止它後面的代碼。後面的代碼可能會在異步函數的回調函數之前執行。一旦異步函數完成,就會調用回調函數。 –