JVG*_*JVG 2 javascript asynchronous mongodb node.js
我正在Node中构建一个函数来查询我的mongoDB数据库并将一些结果返回到一个对象中.我无法正确设置对象.这是我的代码:
调用MongoDB查找的函数
$scope.listItems = $resource('http://10.1.1.21\\:3000/api/uniques/:query');
var itemsToList = [
'designer',
'store',
'category'
]
$scope.uniqueLists = {};
for(var i = 0; i<itemsToList.length; i++){
$scope.uniqueLists[itemsToList[i]] = [];
$scope.listItems.get({query:itemsToList[i]}, function(data){
console.log(itemsToList); // Returns ["designer", "store", "Category"] x3
console.log(itemsToList[i]); // Returns undefined, undefined, undefined
console.log('i = ' + i); // Returns 3, 3, 3 (which is really odd, ideas?)
$scope.uniqueLists[i] = data.query;
});
}
Run Code Online (Sandbox Code Playgroud)
此代码的问题在上面的注释中.奇怪的是,i == 3对于所有3个循环,当它应该相等0时1,然后完成2.
我的问题是
任何人都可以了解这里发生的事情吗?它可能与Node的异步行为有关,但我真的很茫然.
附加信息
我正在访问的ExpressJS电话$scope.listItems是在这里,你可以看到express通过res(ponse)提供数据,据我所知,我无法传入i或itemsToList在这里:
exports.uniqueEntries = function(req, res){
var query = req.params.query;
console.log(query);
db.products.distinct(query, function(err, results){
if (err) {
console.log("Lookup Error: " + err);
} else{
res.json({
query:results
});
}
});
}
Run Code Online (Sandbox Code Playgroud)
也许问题是,在expressJS查找完成时,三个for循环已完成并且i == 2.我不知道为什么控制台会记录它i ==3,我也不知道如何阻止循环以确保在继续下一个for循环之前完成查找.
$resource方法,包括get(),是异步的.因此,他们的回调将在稍后调用.并且,在这种情况下,稍后是for循环运行完成之后.
对于回调中的任何语句,i将会增加到3,这就是为什么它不再0是1,或者2为:
console.log('i = ' + i);
Run Code Online (Sandbox Code Playgroud)
你可以i通过在回调周围为它创建一个闭包来保持每个值的增加function:
function createCallback(itemsToList, i) {
return function (data) {
console.log(itemsToList); // Returns ["designer", "store", "Category"] x3
console.log(itemsToList[i]); // Returns undefined, undefined, undefined
console.log('i = ' + i); // Returns 3, 3, 3 (which is really odd, ideas?)
$scope.uniqueLists[i] = data.query;
};
}
for(var i = 0; i<itemsToList.length; i++){
$scope.uniqueLists[itemsToList[i]] = [];
$scope.listItems.get({query:itemsToList[i]}, createCallback(itemsToList, i));
}
Run Code Online (Sandbox Code Playgroud)
另一个选项,假设itemsToList是一个Array,可以使用.forEach()就地for循环,因为迭代器将是闭包:
itemsToList.forEach(function (item, i) {
$scope.uniqueLists[item] = [];
$scope.listItems.get({query:item}, function(data){
console.log(itemsToList);
console.log(itemsToList[i]);
console.log('i = ' + i);
$scope.uniqueLists[i] = data.query;
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2416 次 |
| 最近记录: |