在Angular $ resource函数的回调中,变量突然变为未定义

时间:2013-07-14 08:18:12

标签: javascript node.js mongodb asynchronous

我正在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个循环,当它应该等于01时,然后在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循环之前完成查找。

2 个答案:

答案 0 :(得分:5)

$resource methods,包括get(),是异步的。因此,他们的回调将被称为以后。并且,在这种情况下,以后是在for循环运行完成之后。

对于回调中的任何陈述,i已经增加到3,这就是为什么它不再是01或{{1} for:

2

您可以通过围绕回调console.log('i = ' + i); 为其创建closure来保持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)); } itemsToList,可以使用.forEach()代替Array循环,因为迭代器将是闭包:

for

答案 1 :(得分:0)

当你看一下jQuery文档(http://api.jquery.com/jQuery.get/)时,你会发现$ .get是以下内容的缩写:

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

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

相关问题