【问题标题】:Angular js call back after multiple http calls complete with foreach使用foreach完成多个http调用后Angular js回调
【发布时间】:2016-07-13 22:36:13
【问题描述】:

我正在发送多个 HTTP 调用以更新 foreach 循环内的项目,并且在所有请求完成后需要回调。我找到了this,但没有帮助。

我的代码:

$q.all(_($scope.students.items).each(function(item) {
   $scope.student.update(); //this is an http call
})).then(function() {
   // I need a callback need here
   alert("complete"); //should be shown after all students get updated but it is
                      // called before all network calls got complete
});

这里是通用更新函数

self.update = function(item, callback) {
   that.post(item, self.getUrl("update") , function(err, data) {
      if (self.formatter) {
         data = self.formatter(data);
      }
      callback(err, data);
   });
 };

有什么建议吗?

【问题讨论】:

  • 在这里贴一个$scope.student.update()函数的代码。
  • 你为什么打电话给将军$scope.student.update();而不使用item
  • 这是对 api 服务的通用调用,如果对我的问题有帮助,我可以在更新此学生后使用回调。如下 $scope.student.update(function(){callback here})
  • @Rhumborl 不,我需要项目来设置学生属性我已经删除了代码以保持我的问题简单

标签: javascript angularjs


【解决方案1】:

您在update() 函数中错过了return 关键字,因为它必须返回一个承诺(当然,that.post() 函数也必须返回一个承诺):

self.update = function(item, callback) {
   return that.post(item, self.getUrl("update") , function(err, data) {
      if (self.formatter) {
         data = self.formatter(data);
      }
      callback(err, data);
   });
 };

那么这应该可以工作:

var promises = [];
_($scope.students.items).each(function(item) {
   promises.push($scope.student.update());
})
$q.all(promises).then(function() {
   alert("complete");
});

【讨论】:

  • @jitender 这真的取决于函数$scope.student.update(); 的样子 - 它必须返回承诺......我也不明白为什么这个函数不带任何参数?
  • @Akarienta 这是一个通用服务,需要解释一下
  • @jitender 重要的是这个函数返回什么
  • 这个函数会在更新后返回学生模型
  • @jitender 是承诺吗?我认为问题出在$scope.student.update(); 函数中;不在您发布的代码中
【解决方案2】:
$q.all(_.map($scope.students.items, function(item) {
   return item.update();
})).then(function() {
   //everything has completed
});

$scope.student.items 中每个项目的更新函数必须返回承诺才能使其工作。比如:

function update() {
   return $http( ... );
}

【讨论】:

  • 虽然所有请求都在网络中挂起,但它的显示警报不起作用
【解决方案3】:

你也可以试试这个map

$q.all(_($scope.students.items).map(function(item) {
  item.update();
})).then(function() {
  alert("complete");
});

我已经用下面的 sn-p 更新了这里的代码。我使用了一些返回简单承诺的方法。包括您可以执行此操作的两种方法。

  • 将 Promise 推入数组并使用 q.all
  • 在 q.all 中使用地图

angular.module('demoApp', []).controller('DemoController', function($scope, $q, $timeout) {
  var a = function() {
    var deferred = $q.defer();
    console.log('Executing a');
    deferred.resolve();
    return deferred.promise;
  };
  var b = function() {
    var deferred = $q.defer();
    console.log('Executing b');
    deferred.resolve();
    return deferred.promise;
  };
  var c = function() {
    var deferred = $q.defer();
    console.log('Executing c');
    deferred.resolve();
    return deferred.promise;
  };
  var f = [{
    call: a
  }, {
    call: b
  }, {
    call: c
  }];

  $scope.mapTest = function() {
    $q.all(f.map(function(item) {
      return item.call();
    })).then(function() {
      console.log("complete");
    });

  };
  $scope.promisePush = function() {
    var promises = [];
    angular.forEach(f, function(item) {
      promises.push(item.call());
    });
    $q.all(promises).then(function() {
      console.log('complete');
    });
  };


});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="demoApp">
  <div ng-controller="DemoController">
    <button ng-click="mapTest()">Q.all using map</button>
    <button ng-click="promisePush()">Q.all using promise push</button>
  </div>
</body>

【讨论】:

  • 所有请求完成后
  • @Srijith 应该是 return item.update(),不是吗?
  • 非常感谢它对我的帮助
【解决方案4】:

您不应该在 foreach 中发送相同的 ajax。这应该是单个 ajax 并且更新应该在回调中完成,所以发送一个像“studentsUpdate”这样的 ajax 并作为响应对学生集合执行 foreach 并更新对象数据。好的做法是减少 ajax 调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 2017-11-10
    • 2018-10-30
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多