Angular 异步服务

Angular async service

我正在尝试通过自定义服务中的 $http 服务进行 ajax 调用。然后我想在我的控制器中自定义在自定义服务中接收到的数据。

我将自定义数据功能包装在控制器内 $interval 中:这样我就可以在收到数据时自定义数据。

问题是:虽然数据正确记录在服务中,服务似乎没有return任何东西,虽然它应该 returned (return response.data.Items)

因此 $interval 无限循环,我无法自定义数据。

var myApp = angular.module('MyApp', []);


myApp.service('ajaxcall', ['$http', function($http) {

    this.getjson = function () {

        $http.get("http://localhost:3000/one")
            .then(function(response) {

            console.log(response.data.Items);  //data logged correctly
            return response.data.Items;
        });
    }
}])

.controller('MyCtrl', ['$scope', '$interval', 'ajaxcall', function($scope, $interval, ajaxcall) {

    var new_items = ajaxcall.getjson();

    customize_data = $interval(function () {  //loops indefintely, new_items=undefined, why?
                         if (new_items) {
                             // customize data
                         }
                     }, 200);

    for(var i=0; i<new_items.length; i++) {
        $scope.items.push(new_items[i]);
    }
}]);

你可以说:把自定义数据功能移到自定义服务里就行了。首先,我根本不想这样做。其次它甚至没有意义:$scope 在服务中不可用,所以无论如何我应该等待 $http 回复。

如果你想获取return数据,你会写一个工厂而不是服务!

代码:

myApp.factory('ajaxcall', ['$http', function($http) {
  return {
    getjson : function () {

        $http.get("http://localhost:3000/one")
            .then(function(response) {

            console.log(response.data.Items);  //data logged correctly
            return response.data.Items;
        });
    }
}
}])

您滥用了由您的异步调用调用的 promise return。这是您需要在控制器中执行的更改数据的操作:

ajaxcall.getjson()
.then(function(new_items) {
    // customize data

    // this part should go here as well
    for(var i=0; i<new_items.length; i++) {
      $scope.items.push(new_items[i]);
    }
});

无需使用 intervalstimeouts。请注意,ajaxcall.getjson() 不是 return 您的数据,它 return 是与您的项目一起解决的承诺。

阅读 angular 中的 promises

从服务进行 http 调用时使用 promise

myApp.service('ajaxcall', ['$http', '$q', function($http, $q) {
    this.getjson = function() {
      var q = $q.defer();
      $http.get("http://localhost:3000/one")
        .success(function(data) {
          console.log(data); //data logged correctly
          q.resolve(data);
        })
      .error(function(err) {
        q.reject(err);
      });
      return q.promise;
    }
  }]);

更改控制器以等待 promise

ajaxcall.getjson()
 .then(function(data){
    console.log(data);
 });

我想指出几件事。

  1. this.getjson 方法中执行 return $http 承诺,以便您可以在从中获取数据时链接该承诺。

    this.getjson = function() {
      //returned promise here
      return $http.get("http://localhost:3000/one")
        .then(function(response) {
        console.log(response.data.Items); //data logged correctly
        return response.data.Items;
      });
    }
    

  1. var new_items = ajaxcall.getjson() 行未存储由 getjson 调用 return 编辑的数据,它将具有您当前获取的未定义值。完成上述更改后,new_items 将遵守 ajaxcall.getjson 的承诺 return。此后使用 $q.when 关注 promise 以得到解决并检查其 .then 函数中的数据。

    customize_data = $interval(function() { //loops indefintely, new_items=undefined, why?
      $q.when(new_items).then(function(res) {
        if (customizeData) {
          //Do Logic
        }
      })
    }, 200);
    

Side Note: You could face problem with this code, as you had 200ms time for each interval . Which can make multiple ajax calls before completing the last call(which would be kind of unexpected behaviour). To resolve such issue you could use $interval.cancel(customize_data); //once desired interval work has done