49

我的服务是:

myApp.service('userService', [
  '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
    var deferred;
    deferred = $q.defer();
    this.initialized = deferred.promise;
    this.user = {
      access: false
    };
    this.isAuthenticated = function() {
      this.user = {
        first_name: 'First',
        last_name: 'Last',
        email: 'email@address.com',
        access: 'institution'
      };
      return deferred.resolve();
    };
  }
]);

我通过以下方式在我的config文件中调用它:

myApp.run([
  '$rootScope', 'userService', function($rootScope, userService) {
    return userService.isAuthenticated().then(function(response) {
      if (response.data.user) {
        return $rootScope.$broadcast('login', response.data);
      } else {
        return userService.logout();
      }
    });
  }
]);

但是,它抱怨这then不是一个功能。我不是在返回已解决的承诺吗?

4

7 回答 7

106

如何在 AngularJS 中简单地返回一个预先解决的承诺

已解决的承诺:

return $q.when( someValue );    // angularjs 1.2+
return $q.resolve( someValue ); // angularjs 1.4+, alias to `when` to match ES6

被拒绝的承诺:

return $q.reject( someValue );
于 2015-06-11T11:08:55.293 回答
34

返回你的承诺,返回 deferred.promise。
它是具有 'then' 方法的 promise API。

https://docs.angularjs.org/api/ng/service/$q

调用resolve 不会返回一个promise,它只是表示promise 已解决,因此它可以执行“then”逻辑。

基本模式如下,冲洗并重复
http://plnkr.co/edit/fJmmEP5xOrEMfLvLWy1h?p=preview

<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@*" data-semver="1.3.0-beta.5" 
        src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>

<div ng-controller="test">
  <button ng-click="test()">test</button>
</div>
<script>
  var app = angular.module("app",[]);

  app.controller("test",function($scope,$q){

    $scope.$test = function(){
      var deferred = $q.defer();
      deferred.resolve("Hi");
      return deferred.promise;
    };

    $scope.test=function(){
      $scope.$test()
      .then(function(data){
        console.log(data);
      });
    }      
  });

  angular.bootstrap(document,["app"]);

</script>

于 2014-05-09T14:42:50.080 回答
21

从您的服务方法:

function serviceMethod() {
    return $timeout(function() {
        return {
            property: 'value'
        };
    }, 1000);
}

在你的控制器中:

serviceName
    .serviceMethod()
    .then(function(data){
        //handle the success condition here
        var x = data.property
    });
于 2014-05-09T14:52:53.970 回答
4

这是您的服务的正确代码:

myApp.service('userService', [
  '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {

    var user = {
      access: false
    };

    var me = this;

    this.initialized = false;
    this.isAuthenticated = function() {

      var deferred = $q.defer();
      user = {
        first_name: 'First',
        last_name: 'Last',
        email: 'email@address.com',
        access: 'institution'
      };
      deferred.resolve(user);
      me.initialized = true;

      return deferred.promise;
    };
  }
]);

然后你的控制器应该相应地对齐:

myApp.run([
  '$rootScope', 'userService', function($rootScope, userService) {
    return userService.isAuthenticated().then(function(user) {
      if (user) {
        // You have access to the object you passed in the service, not to the response.
        // You should either put response.data on the user or use a different property.
        return $rootScope.$broadcast('login', user.email);  
      } else {
        return userService.logout();
      }
    });
  }
]);

关于服务的几点注意事项:

  • 仅在服务中公开需要公开的内容。用户应保留在内部,并且只能由 getter 访问。

  • 在函数中,请使用“我”,这是使用 javascript 避免这种极端情况的服务。

  • 我猜到了初始化的意思,如果我猜错了,请随时纠正我。

于 2014-05-09T18:56:24.797 回答
2

要返回已解决的承诺,您可以使用:

return $q.defer().resolve();

如果您需要解决某些问题或返回数据:

return $q.defer().resolve(function(){

    var data;
    return data;

});
于 2015-06-03T19:59:50.823 回答
1

对于较短的 JavaScript 代码,请使用:

myApp.service('userService', [
  '$q', function($q) {
    this.initialized = $q.when();
    this.user = {
      access: false
    };
    this.isAuthenticated = function() {
      this.user = {
        first_name: 'First',
        last_name: 'Last',
        email: 'email@address.com',
        access: 'institution'
      };
      return this.initialized;
    };
  }
]);

您知道通过用新对象覆盖它而不是仅设置对象属性来释放与 userService.user 的绑定吗?

这是我的 plnkr.co 示例代码示例的意思(工作示例: http ://plnkr.co/edit/zXVcmRKT1TmiBCDL4GsC?p=preview ):

angular.module('myApp', []).service('userService', [
    '$http', '$q', '$rootScope', '$location', function ($http, $q, $rootScope, $location) {
    this.initialized = $q.when(null);
    this.user = {
        access: false
    };
    this.isAuthenticated = function () {
        this.user.first_name = 'First';
        this.user.last_name = 'Last';
        this.user.email = 'email@address.com';
        this.user.access = 'institution';
        return this.initialized;
    };
}]);

angular.module('myApp').controller('myCtrl', ['$scope', 'userService', function ($scope, userService) {
    $scope.user = userService.user;
    $scope.callUserService = function () {
        userService.isAuthenticated().then(function () {
            $scope.thencalled = true;
        });
    };
}]);
于 2014-09-23T07:00:06.697 回答
0

尝试这个:

myApp.service('userService', [
    '$http', '$q', '$rootScope', '$location', function($http, $q, $rootScope, $location) {
      var deferred= $q.defer();
      this.user = {
        access: false
      };
      try
      {
      this.isAuthenticated = function() {
        this.user = {
          first_name: 'First',
          last_name: 'Last',
          email: 'email@address.com',
          access: 'institution'
        };
        deferred.resolve();
      };
    }
    catch
    {
        deferred.reject();
    }

    return deferred.promise;
  ]);
于 2014-05-09T15:14:18.123 回答