如何使函数等待异步调用完成?

时间:2012-12-24 06:23:02

标签: angularjs

我有angularjs服务来获取json数据。

// Controller.js file
$scope.data=Events.query();

$scope.getEventtypes = function(){
    angular.forEach($scope.data,function(value, key){
        var arr = [];
        if(key==$scope.month+$scope.year)  {
            for(var i=0; i<key.length; i++) {
                arr.push(value[i].type);
                $scope.eventtypes=arr.unique();
            }
        }
    });
};

在尝试访问value[i].type时会抛出错误无法读取未定义的属性type。我知道这是因为异步调用。

//i want to add success function like this
$http.get('').success(function(data) {
....
});
谁能帮助我?如果你建议做一些比这更有效的事情会更好。谢谢

3 个答案:

答案 0 :(得分:6)

我使用异步$ http服务(使用jsonp)得到了类似的答案。

基本上你需要:

  • 使用回调或
  • 使用承诺对象

承诺:

var promise = service.getHistoricalDataWithQ($scope.symbol, $scope.startDate, $scope.endDate);

promise.then(function(data) {
   $scope.items = data;
});            

使用回调:

service.getHistoricalDataWithCallback(function (data) {
    $scope.items = data;
}, $scope.symbol, $scope.startDate, $scope.endDate);

请参阅答案Angular using $htp and YQL

查看我的jsFiddle

答案 1 :(得分:2)

虽然@Mahbub建议是正确的方向(承诺使协调异步函数更容易),但它并不是唯一的技术。好的,旧的回调也会起作用。虽然承诺可以说是更优雅的API,但是在当前版本的AngularJS中,{API支持API}作为$resource的一部分不受支持。

除了理论之外,在您的特定情况下,您可以简单地使用回调并完成它:

$scope.data=Events.query(function(data){

   angular.forEach(data,function(value, key){
        var arr = [];
        if(key==$scope.month+$scope.year)  {
            for(var i=0; i<key.length; i++) {
                arr.push(value[i].type);
                $scope.eventtypes=arr.unique();
            }
        }
    });
});

答案 2 :(得分:1)

为了使这个工作,$ resource需要返回一个像$ http那样的promise对象。但angular的最新版本尚不支持。

Partap的标记是“很好合并”,它返回$ resource的承诺。 https://github.com/angular/angular.js/pull/1547。您需要使用此https://github.com/partap/angular.js/blob/005e865e5629a241d99c69a18f85fc2bb5abb1bc/src/ngResource/resource.js

更改resource.js文件

所以你可以使用它并重新考虑你的代码

Events.query().$q.then(function(response){
 $scope.data=response;
 ....
 ....
});