在Angular中一起使用Promise和服务

时间:2013-01-15 07:27:54

标签: http angularjs

我的问题基于Angular Google小组中的this topic 我想提供一个服务,它存储从后端通过$ http检索的一些基本数据,然后我只需要获取这些数据一次。喜欢,

var load = function() {
   return $http.get(...).then(function(data) {
       return data.user; 
   });
};

module.factory("userProvider", function() {
    var user;
    var getUser = function() {
        if(!user) {
            load().then(function(data) {
               user = data;
           });
        }
        return user;
    };
    return {
        getUser : getUser
    }
});

module.controller("UserController", ["userProvider", function UserController("userProvider") {
    var user = userProvider.getUser();
    // do something with user
}]);

问题在于promise链在userProvider中结束但在控制器中没有,因此在我第一次使用此控制器时未定义用户,因为尚未返回数据。

如何使用此类存储服务并正确返回数据?谢谢!

2 个答案:

答案 0 :(得分:19)

您可以创建自己的承诺。这是修改后的代码:

module.factory( "userProvider", function( $q ) {
  // A place to hold the user so we only need fetch it once.
  var user;

  function getUser() {
    // If we've already cached it, return that one.
    // But return a promise version so it's consistent across invocations
    if ( angular.isDefined( user ) ) return $q.when( user );

    // Otherwise, let's get it the first time and save it for later.
    return whateverFunctionGetsTheUserTheFirstTime()
    .then( function( data ) {
      user = data;
      return user;
    });
  };

  // The public API
  return {
    getUser: getUser()
  };
});

更新: @yohairosen下面的解决方案在很多情况下都很棒,但并非适用于所有情况。在某些情况下,我们只想缓存成功的结果,就像我在这里所做的那样。例如,如果此请求失败表明用户需要先登录,我们就不希望下次调用(可能是在登录后)来传递缓存失败。如果在所有情况下该方法不一定与呼叫一致,则该方法更好;在所有其他情况下,@ yohairosen的解决方案更简单并且推荐。

答案 1 :(得分:17)

创建自己的承诺有点开销,角度的$ http无论如何为你创造一个。您正在寻找的是缓存,http可以通过将cache:true传递给服务调用来为您处理。

所以你可以简单地做这样的事情:

 module.factory("userProvider", function() {
   var getUser = function() {
   return $http.get(..., {cache:true}).then(function(data) {
       return data.user; 
   });

   return {
       getUser : getUser
   }
});