【问题标题】:How can I create a service that returns the value promise如何创建返回价值承诺的服务
【发布时间】:2016-03-12 18:04:01
【问题描述】:

我想创建一个返回 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');
   }
});

【问题讨论】:

    标签: angularjs angular-promise angular-services


    【解决方案1】:

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

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

    【讨论】:

    • 所以只有在我最常运行then方法的控制器中?根本不可能在服务中运行它吗?因为我有一些控制器,我希望它们与此服务一起使用,所以我想在服务中使用then 方法进行测试
    • 这取决于你想在哪里使用数据。您可以在服务中运行 .then 方法,但是您必须在该处使用结果。如果你想将结果从服务传递给控制器​​,你也必须返回一个承诺。
    【解决方案2】:

    你想错了。服务总是返回一个承诺,因为没有从 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】:

      如果数据存在,只需在 Promise 中解析即可。

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

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

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

      【讨论】:

      • 谢谢你的回答我是这样做控制器的:controller: function($scope, $stateParams, getContent) { getContent(BASE_URL + $stateParams.page + '?angular=pageName').then(function(res){ // By || Operator - get the promise of $htpp or the promise of $q $scope.contentPage = res.data || res; }); }
      • 很高兴听到!如果您觉得这有帮助,请将其标记为已接受。保持未回答的队列干净是件好事。
      【解决方案4】:

      您的服务正在返回当前所写的承诺。一个承诺永远是一个承诺,因为你真的不知道它什么时候会完成。然而,对于 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.
             }
      
         }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-24
        • 1970-01-01
        • 2021-06-29
        • 2019-07-12
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 2018-03-15
        相关资源
        最近更新 更多