异步函数和javascript变量范围的问题

时间:2014-12-16 14:33:13

标签: javascript angularjs angular-promise

我有以下代码调用REST Web服务。 Web服务返回boolean

    checkCurrentPassword: function (passwordInfo) {
        var valid = false;
        $http.post('/api/preference/password/check', passwordInfo)
            .success(function (data) {
                valid = data;
            });
        return valid;
    }

问题是,当checkCurrentPassword返回valid仍为false时,因为ajax调用由于其异步性质而未完成。

我不确定如何确保valid变量已正确分配从服务器返回的值。

有人可以帮忙吗?

编辑1

使用回调,似乎我只是将问题驱逐到控制器层......见下文:

角度服务

checkCurrentPassword: function (passwordInfo, callback) {
              return  $http.post('/api/preference/password/check', passwordInfo)
                    .success(function (data) {
                        callback(data);
                    });
            }
来自角度控制器的

 $scope.updatePassword = function () {
            if ($scope.updatePasswordForm.$valid) {

                var valid = false;

                passwordService.checkCurrentPassword({plainPassword: $scope.passwordInfo.currentPassword}, function(data, status){
                    valid = data;
                });

                console.log(valid);//always false

                passwordService.updatePassword($scope.passwordInfo, function (data, status) {
                    console.log('Updated password successfully');
                    $state.go('dashboard');
                });
            }
        };

编辑2 :这是我重写控制器的方式:

$scope.updatePassword = function () {
            if ($scope.updatePasswordForm.$valid) {
                passwordService.checkCurrentPassword({plainPassword: $scope.passwordInfo.currentPassword}).success(function (data) {
                    if (data) {
                        passwordService.updatePassword($scope.passwordInfo, function (data, status) {
                            console.log('Updated password successfully');
                            $state.go('dashboard');
                        });
                    }
                });
            }
        };

3 个答案:

答案 0 :(得分:1)

您应该返回$http.get返回的承诺(HttpPromise),请参阅:https://docs.angularjs.org/api/ng/service/ $ q和https://docs.angularjs.org/api/ng/service/ $ http

此示例可能对您有所帮助:

angular.module('app',[]);

angular.module('app').service('Foo',function($q){

  this.checkPassword = function(value){
    //replace this example code with a $http call
    console.log('checkPassword:',value);
    var deferred = $q.defer();
    setTimeout(function(){
      if(value && value.length >= 4){
        deferred.resolve(value);        
      } else {
        deferred.reject('oops invalid password!!!');
      }   
    },100);
    return deferred.promise;
  };

  this.updatePassword = function(value){
    //replace this example code with a $http call
    console.log('updatePassword:',value);
    var deferred = $q.defer();
    setTimeout(function(){
      if(Math.random() > 0.5){
        deferred.resolve('password updated');        
      } else {
        deferred.reject('error while updating password');
      }   
    },100);
    return deferred.promise;
  };

});

angular.module('app').run(function(Foo){

  Foo.checkPassword('tolkjlkj')
    .then(Foo.updatePassword)
    .then(function(result){
      console.log('Yes',result);
    }).catch(function(error){
      console.log('Oops',error);
    });

});

答案 1 :(得分:1)

您应该使用angulars's built in $q service

你的功能看起来像这样。 (确保在顶部的代码中注入$ q)

checkCurrentPassword: function (passwordInfo) {

    var deferred = $q.defer();
    var valid = false;

    $http.post('/api/preference/password/check', passwordInfo)
        .success(function(data){
            valid = data;
            deferred.resolve();
        })
        .error(function(error){
            deferred.reject();
        });

    return deferred.promise;

};

答案 2 :(得分:0)

我认为你可以用回调来解决它......

checkCurrentPassword: function (passwordInfo) {

  $http.post('/api/preference/password/check', passwordInfo)
             .success(function (data) {
                 return data;
             }).error(function (data) {
                 return false;
             });

}