如何创建返回值promise的服务

时间:2015-12-07 23:35:02

标签: angularjs angular-promise angular-services

我想创建一个返回json

的服务

或者通过请求到服务器,或者检查它是否已经存在于:Window.content

但我不想从我的控制器那里得到承诺!

我想让json准备好了!

我已经多次试过几次

我尝试使用then方法在我的服务中进行测试

但我还是得到了承诺

(仅限$http,是否使用$q

如果没有从我的控制器获得承诺,我无法获得价值

我的服务:

app.service('getContent',['$http', function( $http ){

      return function(url){   // Getting utl

          if(window.content){ // if it's the first loading, then there is a content here

              var temp = window.content;
              window.content = undefined;
              return temp;
          }

          return $http.get(url);

      };

  }]);

我的控制器:

.state('pages', {
   url: '/:page',
   templateProvider:['$templateRequest',
       function($templateRequest){
           return $templateRequest(BASE_URL + 'assets/angularTemplates/pages.html');
       }],
   controller: function($scope, $stateParams, getContent){ 
       //  Here I want to to get a json ready :
       $scope.contentPage = getContent(BASE_URL + $stateParams.page + '?angular=pageName');
   }
});

4 个答案:

答案 0 :(得分:2)

如果数据存在,只需在承诺中解决。

虽然此过程仍然是异步的,但它不需要网络调用并快速返回。

app.service('getContent',['$http', '$q', function( $http, $q ){

      return function(url){ 
          // create a deferred
          var deferred = $q.defer();
          if(window.content){ // if it's the first loading, then there is a content here

              var temp = window.content;
              window.content = undefined;
              deferred.resolve(temp); // resolve the data
              return deferred.promise; // return a promise
          }

          // if not, make a network call
          return $http.get(url);

      };

  }]);

重申一下,这是异步的,但不需要网络调用。

答案 1 :(得分:1)

这是不可能的。如果负责计算或检索值的代码依赖于promise,那么您将无法返回函数从promise中提取的值。

说明:从控制流程中可以很容易地看出这一点。承诺是异步评估的。从服务器检索json可能需要几秒钟,但函数的调用者不应该等待很长时间,因为整个运行时环境都会阻塞。这就是你首先使用promises的原因。 Promise只是组织回调的好方法。因此,当您的承诺返回时,导致函数调用的事件将已终止。事实上它必须有,否则你的承诺无法评估。

答案 2 :(得分:0)

你在考虑这个错误。服务总是返回一个promise,因为没有从API获取JSON的同步方法:

app.factory('myService', ['$http', function($http) {
    return $http('http://my_api.com/json', function(resp) {
        return resp.data;
    });
}]);

然后您可以在控制器中调用它,如下所示:

app.controller('myController', ['$scope', 'myService', function($scope, myService) {
    myService.then(function(data) {
        $scope.contentPage = data; // here is your JSON 
    }, function(error) {
        // Handle errors
    });
}]);

答案 3 :(得分:0)

您的服务正在回复当前的承诺。承诺永远是一种承诺,因为你不知道什么时候会完成。但是,对于Angular的双向数据绑定,这不是问题。请参阅我的编辑以及docs

$HTTP上的示例

在您的控制器中

controller: function($scope, $stateParams, getContent){

       getContent(BASE_URL + $stateParams.page + '?angular=pageName')
                                    .then(aSuccessFn, aFailedFn);

        function aSuccessFn(response) {
            // work with data object, if the need to be accessed in your template, set you scope in the aSuccessFn.
            $scope.contentPage =  response.data;
        }
       function aFailedFn(data) {
            // foo bar error handling.
       }

   }