2015-07-20 73 views
22

我有以下情况,我需要来自特定url的数据。我写了一个带参数'url'的函数。在函数内部,我有$ http.get方法,它调用了url。数据将被返回到调用函数angularJS中的同步http调用

var getData = function (url) { 
    var data = ""; 

    $http.get(url) 
     .success(function(response, status, headers, config) { 
      data = response; 
     }) 
     .error(function(errResp) { 
      console.log("error fetching url"); 
     }); 
    return data; 
} 

问题如下,$ http.get是异步的,在获取响应之前,函数返回。因此调用函数以空字符串的形式获取数据。如何强制函数不会返回,直到从url中获取数据?

+0

使用像正常回调或承诺有什么问题吗? – Marty

+1

您可能会返回成功和错误功能本身,可以进一步使用... – binariedMe

回答

15

看看承诺克服这样的问题,因为它们使用的所有在这个地方,在有角度的世界。

您需要使用$q

var getData = function (url) { 
    var data = ""; 
    var deferred = $q.defer(); 

    $http.get(url) 
     .success(function(response, status, headers, config) { 
      deferred.resolve(response); 
     }) 
     .error(function(errResp) { 
      deferred.reject({ message: "Really bad" }); 
     }); 
    return deferred.promise; 
} 

这里有一个很好的文章promises and $q

UPDATE:

仅供参考,$http服务本身会返回一个承诺,所以$q不一定在这种情况下需要(因此是anti-pattern)。

但不要让这是跳过阅读$ q和承诺的原因。

所以上面的代码等同于以下内容:

var getData = function (url) { 
    var data = ""; 
    return $http.get(url); 
} 
+0

如何访问承诺的价值? – clearScreen

+0

为什么downvote?哪部分答案不可接受/错误? – nalinc

+1

这是常见的反模式,请参阅:https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns –

5

做你想做的是一个典型的方法是,像这样:

var getData = function(url, callback) { 
    $http.get(url).success(function(response) { 
     callback && callback(response); 
    }); 
}; 

使用,如:

getData('/endpoint', function(data) { 
    console.log(data); 
}); 
4

您的功能似乎是多余的。只需使用$http.get(url),因为无论如何,在使用它之前,您还没有做任何其他事情。

var url = 'foo/bar'; 

$http 
    .get(url) 
    .success(function(response, status, headers, config) { 
     $scope.data = response; 
    }) 
    .error(function(errResp) { 
     console.log("error fetching url"); 
    }); 

或者如果您以后需要访问promise,只需将其分配给变量;

var promise = $http.get(url); 

// some other code.. 

promise.then(function(data){ 
    //.. do something with data 
}); 
8

您可以使用$ q.all()方法还调用函数来解决这个问题

var requestPromise = []; 

var getData = function (url) { 
    var data = ""; 

    var httpPromise = $http.get(url) 
     .success(function(response, status, headers, config) { 
      data = response; 
     }) 
     .error(function(errResp) { 
      console.log("error fetching url"); 
     }); 

    requestPromise.push(httpPromise); 
} 

$q.all(requestPromise).then(function(data) { 

    //this is entered only after http.get is successful 
}); 

确保注入$ Q作为一个依赖。希望它有帮助