2014-03-19 116 views
1

在蒙戈我的用戶名單表設置這樣的:嵌套查詢節點JS/MongoDB的

email: [email protected], uniqueUrl:ABC, referredUrl: ... 

我有下面的代碼,我查詢所有用戶在我的數據庫,併爲每個用戶,找出其他的用戶referredUrl的多少等於當前用戶的唯一網址:

exports.users = function(db) { 
    return function(req, res) { 
    db.collection('userlist').find().toArray(function (err, items) { 
     for(var i = 0; i<= items.length; i++) { 
     var user = items[i]; 
     console.log(user.email); 
     db.collection('userlist').find({referredUrl:user.uniqueUrl}).count(function(err,count) { 
      console.log(count); 
     }); 
     } 
    }); 
    }; 
}; 

現在,我第一次登錄的用戶的電子郵件,然後與用戶相關聯的計數。因此,控制檯應該這樣:

[email protected] 
1 
[email protected] 
3 
[email protected] 
2 

相反,它看起來是這樣的:

[email protected] 
[email protected] 
[email protected] 
1 
3 
2 

這是怎麼回事?爲什麼只有在第一次查詢完成後纔會返回嵌套查詢?

回答

3

歡迎使用異步編程和回調。

你希望發生的事情是,所有東西都以線性順序工作,但這不是節點的工作方式。整個主題在這裏有點過於寬泛,但是可以通過閱讀一些內容。

幸運的是,驅動程序調用的所有密鑰process.nextTick,這給你的東西來查找和搜索。但是由於事情排隊的自然方式,有一種簡單的方法可以補救代碼。

db.collection('userlist').find().toArray(function(err,items) { 
    var processing = function(user) { 
    db.collection('userlist').find({ referredUrl: user.uniqueUrl }) 
     .count(function(err,count) { 
     console.log(user.email); 
     console.log(count); 
    }); 
    }; 
    for(var i = 0; i < items.length; i++) { 
    var user = items[i]; 
    processing(user); 
    } 
}); 

現在當然是真的解釋了這個問題過於簡單的方式,但明白在這裏,你是通過參數傳遞給您的重複.find(),然後做所有的輸出存在的。

如上所述,幸運的是,在API函數中爲您完成了一些工作,並且在添加調用時維護事件堆棧。但大多數情況下,現在輸出呼叫一起並且不發生在不同組事件中。

關於事件循環和回調的詳細解釋,我確信有比這裏寫的更好的東西。

+0

有沒有辦法從進程(用戶)的回調完成時? – Allen

2

回調在node.js中是異步的。所以,您的計數功能(function(err,count) { console.log(count); })不會在console.log(user.email);之後立即執行。因此,輸出是正常的,沒有問題。編碼風格出了什麼問題。在python中(以單線程)以相同的方式調用函數時,不應該連續調用回調來獲得相同的結果。爲了得到理想的結果,你應該在單一回調中完成所有工作。但在這之前,我建議您瞭解回調如何在nodejs中工作。這將顯着幫助您在nodejs中編碼