2

我正在 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;

    });
  }

此代码的问题在上面的评论中。奇怪的是,i == 3对于所有 3 个循环,当它应该等于0,时1,然后在2.

我的问题是

任何人都可以阐明这里发生了什么吗?它可能与 Node 的异步行为有关,但我在这里真的很茫然。

附加信息

我正在访问的ExpressJS电话$scope.listItems在这里,正如您所见express,通过res(ponse) 提供数据,据我所知,我无法通过这里iitemsToList这里:

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  
            });
        }       
    });
}

也许问题在于,当expressJS查找完成时,三个for循环已经完成,并且i == 2. 我不知道为什么控制台会记录它i ==3,我也不知道如何阻止循环以确保在继续下一个for循环之前完成查找。

4

2 回答 2

5

$resource方法,包括get(),是异步的。所以,他们的回调将在稍后被调用。并且,在这种情况下,稍后是在for循环运行完成之后。

对于回调中的任何语句,i将已经递增到3,这就是它不再0是 、12for 的原因:

console.log('i = ' + i);

您可以通过在回调周围为它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));
}

另一个选项,假设itemsToListArray, 可以.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;
  });
});
于 2013-07-14T08:32:04.390 回答
0

当您查看 jQuery 文档 ( http://api.jquery.com/jQuery.get/ ) 时,您会发现 $.get 是:

$.ajax({
    url: url,
    data: data,
    success: success,
    dataType: dataType
});

默认情况下,ajax 调用的 async 属性设置为 true .. ( http://api.jquery.com/jQuery.ajax/ ) 因此,我认为将属性 async 设置为 false 的 ajax 调用的 get 请求更改这就是这里的问题。

于 2013-07-14T08:38:27.233 回答