如何使用$ q从AngularJS服务返回已解决的承诺?

时间:2014-05-09 14:40:49

标签: javascript angularjs promise angular-promise

我的服务是:

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不是一个功能。我不回复已解决的承诺吗?

7 个答案:

答案 0 :(得分:95)

如何在Angular

中简单地返回预先解析的承诺

已解决的承诺:

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

拒绝承诺:

return $q.reject( someValue );

答案 1 :(得分:34)

退还您的承诺,退回deferred.promise 它是具有'then'方法的promise API。

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

调用resolve不会返回它只发出信号的声明 保证承诺得到解决,以便它可以执行'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>

答案 2 :(得分:18)

从您的服务方式:

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

在你的控制器中:

serviceName
    .serviceMethod()
    .then(function(data){
        //handle the success condition here
        var x = data.property
    });

答案 3 :(得分: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();
      }
    });
  }
]);

有关该服务的几点注意事项:

  • 仅在服务中公开需要暴露的内容。用户应该在内部保存,只能由吸气剂访问。

  • 在使用功能时,请使用&#39; me&#39;这是用javascript来避免边缘情况的服务。

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

答案 4 :(得分:2)

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

#include <iostream>
#include <list>
int main(){

    list<int> x = {1,2,3,4};

    *(x.insert(++x.begin(), 3, 2));

    for(auto c : x)
        cout << c;

}

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

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

答案 5 :(得分: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;
        });
    };
}]);

答案 6 :(得分: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;
  ]);