以角js链接承诺

时间:2014-08-07 13:51:58

标签: javascript angularjs q

在角度JS中我有意想不到的behovier。我有一个登录控制器,当我执行登录功能

$scope.Login = function () {

    AuthService.login($scope.credentials).then(function(response){
        $location.path('/categories');
    },
     function(error){
        $scope.error_exist = true;
     switch(error.ExceptionMessage){
        case "201" :
             $scope.error = "The emailAddress/password pair don't match an existing member"; break;
        case "210" :
             $scope.error = "Value cannot be null missing Email Address and/or password."; break;
        case "202" :
             $scope.error = "The email address you are using isn't confirmed. Please see your inbox for further instructions."; break;
        default : 
             $scope.error = "Error with the server";
     }
    });
};

AuthService中的登录功能被点击AccountService.GetUserAccounts时,它会被执行,这是它回调$location.path('/categories');的服务中的另一个函数,它在登录控制器中之后它继续正常执行我想要的是在$location.path('/categories');中的登录功能完成后调用AuthService。 她是AuthService

return $http.post(AuthentoctionControllerUrl, credentials).success(function(response){
               Session.create(response.Name,response.id, response.UserMail);
               AccountService.GetUserAccounts(response.id).then(function(){
                  var acc = AccountService.getAccounts();
                  AccountService.SetUserAccount(acc[0], response.UserMail).then(function(){
                      accIsSet.accSet = true;
                  },
                  function(error){
                      console.log(error);
                  });
               },
               function(error){
                   console.log(result);
               });

            deferred.resolve(response);
           }).error(function(error){
               deferred.reject(error);
           });

            return deferred.promise;
        };

另外AccountService

AccountFactory.GetUserAccounts = function(userID){
            var deferred = $q.defer();
            return $http({method : "post", url:ConfigService.baseUrl+UserURl, data: userID})
                         .success(function(response){
                            for(var i = 0; i<response.length; i++)
                            userAccounts.push(response[i].AccName);
                            $cookieStore.put("userAccounts",userAccounts);
                            deferred.resolve(response);
                         }).error(function(error){
                            deferred.reject(error);
                            console.log(error);
                         });
                return deferred.promise;
        };

        AccountFactory.SetUserAccount = function(accName, userMail){
            var deferred = $q.defer();
                        return $http({method : "post", url:ConfigService.baseUrl+AccountUrl+"?accName="+accName+"&userMail="+userMail})
                         .success(function(response){
                            $cookieStore.put('AuthorizationHeader', response.Token);
                            AccSession.create(response.IsAdmin);
                            deferred.resolve(response);
                         }).error(function(error){
                            deferred.reject(error);
                            console.log(error);
                         });
                return deferred.promise;
        };
AccountFactory.getAccounts = function(){
    if(userAccounts)
        return userAccounts;
    else
        return null;
};

她是代码的编辑,我仍然有同样的行为。

 authService.login = function(credentials) {
           return $http.post(AuthentoctionControllerUrl, credentials).success(function(response){
               Session.create(response.Name,response.id, response.UserMail);
              return AccountService.GetUserAccounts(response.id).then(function(){
                  return AccountService.getAccounts();
              }).then(function(acc) {
                 return AccountService.SetUserAccount(acc[0], response.UserMail);
              }).then(function() {
                      accIsSet.accSet = true;
              });
           });
        };
 AccountFactory.GetUserAccounts = function(userID){
           return $http({method : "post", url:ConfigService.baseUrl+UserURl, data: userID})
                         .success(function(response){
                            console.log("ssss");
                            for(var i = 0; i<response.length; i++)
                            userAccounts.push(response[i].AccName);
                            $cookieStore.put("userAccounts",userAccounts);
                             return response;
                         });
        };

        AccountFactory.SetUserAccount = function(accName, userMail){
                        return $http({method : "post", url:ConfigService.baseUrl+AccountUrl+"?accName="+accName+"&userMail="+userMail})
                         .success(function(response){
                            $cookieStore.put('AuthorizationHeader', response.Token);
                            AccSession.create(response.IsAdmin);
                            return response;
                         });
        };

        AccountFactory.getAccounts = function(){
            if(userAccounts)
                return userAccounts;
            else
                return null;
        };

        return AccountFactory;
    }]);

2 个答案:

答案 0 :(得分:2)

调用

$ http 服务时,返回一个promise。承诺包含方法 .then() .catch() .finally(),它们也会返回一个承诺。此外, $ http 服务的 .success() .error()方法会返回一个承诺。因此,通过$q.defer()创建承诺并像这样解决它是多余的。如果您想获得成功的响应值,您只需返回它,如下所示。

更改您的AuthService.login()以返回以下内容:

return $http.post(AuthentoctionControllerUrl, credentials)
    .success(function(response) {
        Session.create(response.Name,response.id, response.UserMail);

        return AccountService.GetUserAccounts(response.id)
            .then(function(acc) {
                return AccountService.SetUserAccount(acc[0], response.UserMail);
            }).then(function() {
                accIsSet.accSet = true;
            });
    });

和你的AccountFactory

AccountFactory.GetUserAccounts = function(userID){
    return $http({method : "post", url:ConfigService.baseUrl+UserURl, data: userID})
         .success(function(response){
            for(var i = 0; i<response.length; i++)
                userAccounts.push(response[i].AccName);
            $cookieStore.put("userAccounts",userAccounts);
            return response;
         });
};

AccountFactory.SetUserAccount = function(accName, userMail){
    return $http({method : "post", url:ConfigService.baseUrl+AccountUrl+"?accName="+accName+"&userMail="+userMail})
        .success(function(response){
            $cookieStore.put('AuthorizationHeader', response.Token);
            AccSession.create(response.IsAdmin);
            return response;
        });
};

注意:错误处理应该在控制器逻辑中,除非对于需要在工厂/服务本身内更改某些状态的特殊情况,这将是一个例外。如果您将捕获错误,请确保返回响应,以便依赖于它的控制器/工厂/服务中的错误处理程序仍然可以访问响应。

答案 1 :(得分:1)

我在@ryeballar的帮助下解决了这个问题

authService.login = function(credentials) {
            var defferd = $q.defer();
            $http.post(AuthentoctionControllerUrl, credentials).success(function(response){
               Session.create(response.Name,response.id, response.UserMail);
              return AccountService.GetUserAccounts(response.id).then(function(acc){
                  if(acc.data.length !=0)
                    return AccountService.SetUserAccount(acc.data[0].AccName, response.UserMail);
                  else
                      return 0;
              }).then(function(data) {
                  if(data)
                    accIsSet.accSet = true;

                  defferd.resolve(response);
              });
           }).error(function(error){
                defferd.reject(error);
            });
                return defferd.promise;
        };

修改了Auth服务以在成功方法结束时解析承诺,因此控制器中的方法将按预期触发