你如何处理angularJS中$ http.post的异步返回?

时间:2015-11-20 08:50:56

标签: javascript angularjs asynchronous

这里有一个简单的基本登录问题。我的AuthService工厂里面有以下代码(2个相关函数和一个局部变量):

  var username = '';

 function login(uname, upwd, utype) {

// create a new instance of deferred
var deferred = $q.defer();


$http({
        method: 'POST',
        url: '/root',
        headers: {
            'Content-Type': 'application/json'
        },
        data: {
            username: uname,
            password: upwd,
            type: utype
        }

    }).success(function(data, status, headers, config) {
        if (status === 200) {
            user = true;
            username = data.username;
            usertype = data.usertype;
            deferred.resolve();
        } else {
            user = false;
            deferred.reject();
        }

    })
    .error(function(data, status, headers, config) {
        user = false;
        deferred.reject();
    });

  // return promise object
  return deferred.promise;

}

function getusername() {

      return username;
    }

我的控制器看起来像这样:

angular.module('smApp').controller('rootloginController', ['$scope', '$location', 'notificationFactory', 'AuthService',
function($scope, $location, notificationFactory, AuthService) {

    $scope.submit = function() {
        AuthService.login($scope.rEmail, $scope.rootPassword, 'root')
        if (AuthService.isLoggedIn()) {
            $location.url('/dashboard');
            notificationFactory.success('Logged in as ' + rootEmail);
        } else {
            //ngNotifier.notifyError($scope.rEmail);

            notificationFactory.error('Invalid username & password combination');
        }
    };
    };
    }]);

我在login()之后在if statementright中调用我的getusername(),并且因为登录有$ http发布它是异步的,我想我在这里碰壁了。

所以我的主要问题是第一次点击总是给我错误信息,第二次点击就会让我进入。我假设这与承诺没有立即完成并花费一些时间来执行。我想知道是否还有这个?我真的没有任何其他代码在等待旁边执行,因为这是一个登录页面并且使用超时似乎不是正确的方法。

2 个答案:

答案 0 :(得分:3)

在这种情况下,您需要使用Promise API。通过$http服务对服务器的调用返回一个承诺,允许绑定.success.error方法。

.then方法可用作.success.error的简写。它接受两个分别在成功和错误场景中执行的函数。在这些函数中返回一个promise可以将调用链接到服务器。

在大多数情况下,这应该足够了:

// In service 
login: function () {
    return $http.post('your:url').then( // `then` here is optional, but possible
        function () {}, // update service values without having to involve the controller (and/or transform the response object)
        function () {}  // throw error log mesages
    )
}

// In controller
$scope.submit = function () {
    AuthService.login().then(
        function () {
            // success logic: redirect, assign scope variables, etc
        },
        function () {
            // error logic: allow retry
        }
    );
}

答案 1 :(得分:1)

登录请求完成后,您必须致电AuthService.isLoggedIn()。为此,首先返回您创建的延迟对象的承诺。

function login(uname, upwd, utype) {
    // create a new instance of deferred
    var deferred = $q.defer();
    $http({ 
        method: 'POST',
        ...

    return deferred.promise;    
}

现在,您可以等待请求完成。

AuthService.login($scope.rEmail, $scope.rootPassword, 'root').finally(function() {
    if (AuthService.isLoggedIn()) {
        $location.url('/dashboard');
        notificationFactory.success('Logged in as ' + rootEmail);
    } else {
        //ngNotifier.notifyError($scope.rEmail);

        notificationFactory.error('Invalid username & password combination');
    }
});