我怎样才能创建一项 returns 价值承诺的服务

How can I create a service that returns the value promise

我想创建一个 returns json

的服务

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

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

我想要 json 准备好!

几种方式我都试过几次

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

但我还是得到了承诺

(是否只带$http,是否带$q)

如果我的 Controller 没有承诺,我无法获得该值

我的服务:

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');
   }
});

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

解释:这个从控制流程上很容易看出来。一个承诺是异步评估的。从服务器检索 json 可能需要几秒钟,但您函数的调用者不应该等待这么久,因为您的整个运行时环境会阻塞。这就是您首先使用承诺的原因。 Promises 只是组织回调的好方法。所以当你的 promise returns 时,导致函数调用的事件已经终止。其实必须有,不然你的承诺无法评价。

你想错了。服务总是 returns 承诺,因为没有从 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
    });
}]);

如果数据存在,只需在promise中解决即可。

虽然这个过程仍然是异步的,但它不需要网络调用并且 returns 很快。

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);

      };

  }]);

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

您的服务正在返回当前写入的承诺。承诺永远是承诺,因为你真的不知道它什么时候会完成。然而,对于 Angular 的 2 路数据绑定,这不是问题。请参阅下面我的编辑以及 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.
       }

   }