【问题标题】:Foreach into foreach with $http promise使用 $http 承诺 Foreach 进入 foreach
【发布时间】:2016-04-17 21:33:51
【问题描述】:

我正在尝试通过 forEach 根据各种服务的响应创建一个对象 .. 我没有得到我需要的结果。 我知道我应该使用内部迭代承诺,但还不知道如何..

编辑:

嗯..我需要做的就是将一个对象的数据填入$foreach foreach..http中变成一个迭代promise,示例代码:

someservice1.getitem().then(function(){
   var dataInfo= {};
      angular.foreach(data, function(v, k){

         dataInfo[v]=[]
         someservice2.getitem2(k.data).then(function(data){

               datainfo[v].push(data)

         })
     })
$scope.dataInfo = datainfo;
})

所以效果不太好..我认为您可以通过使用承诺来解决,但我做不到。 我希望你的帮助

【问题讨论】:

  • 欢迎来到 SE。不幸的是,就目前而言,您的问题不是任何人都会回答的标准。首先我不会说意大利语,所以我不知道你的代码是什么意思,其次我没有足够的报酬(免费)来阅读你所有的代码来找出你的问题。请您尝试将您的问题压缩到尽可能少的行中,以便我们能够快速回答您的问题。
  • @franco,actividades.listar() 变量中的这个actividades 来自哪里...
  • 第一行不应该是someservice1.getitem().then(function(data){??
  • @mido 您的编辑切换值并键入forEach。应该是angular.foreach(data, function(v,k)。迭代函数的第一个参数应该是值;第二个参数,键。
  • @georgeawg 我只是复制粘贴的佛朗哥的答案,现在更新:)

标签: angularjs foreach promise angular-promise deferred


【解决方案1】:

您正在使用 angularjs,因此使用 $q,对于 Promise 中的 Promise 数组,您可以将您的代码变成这样:

// first add $q service to your controller, 

someservice1.getitem()
  .then(function(data){
    var dataInfo= {};
    var promises = angular.map(data, function(item, index){
      var promises2 = angular.map(item.data, function(iData){
        someservice2.getitem2(iData)
      })
      return $q.all(promises2).then(function(resultArray){
        dataInfo[index] = resultArray;
      });
    });
    return $q.all(promises).then(function(){
      console.log('all data are retrived...');
      $scope.dataInfo = datainfo;
    });
  });

在 ES6 中可能看起来更优雅:

let serviceCall2 = data => someservice2.getitem2(data);  // serviceCall2 is just a closure for someservice2.getitem2() call
someservice1.getitem()
  .then(data => {
    let dataInfo= {}, 
      promises = data.map((item, index) => {
        let promises2 = item.data.map(serviceCall2);
        return $q.all(promises2).then(resultArray => dataInfo[index] = resultArray);
      });
    return $q.all(promises)
      .then(() => {
        console.log('all data are retrived...');
        $scope.dataInfo = datainfo;
      });
  });

【讨论】:

    【解决方案2】:

    问题在于最终的$scope.dataInfo = datainfo;datainfo 对象完成之前提前执行。您需要创建一个承诺,该操作可以安全地链接

    finalPromise.then ( function (datainfo) {
        $scope.dataInfo = datainfo;
    });
    

    你通过returningchaining从之前的promise创建finalPromise

    var service1Promise = 
        someservice1.getitem().then(function(data){
            var promiseList = [];
            angular.foreach(data, function(v,k){
                var p = someservice2.getitem2(k.data);
    
                p.then(function(data) {
                     //return key and data for chaining
                     return { key: k, data: data };
                }) .catch (function (error) {
                     //throw key and error to chain rejection
                     throw { key: k,  error: error };
                });
                //push to list
                promiseList.push(p);
             });
             //return $q.all promise for chaining
             return $q.all(promiseList);
    });
    

    通过链接service1Promise创建finalPromise

    var finalPromise = 
        service1Promise.then(function(fulfilledList) {
            var dataInfoObj = {};
            //assemble data info
            angular.forEach(fulfilledList, function (fulfilledItem) {
                dataInfoObj[fulfilledItem.key] = fulfilledItem.data;
            });
            //return datainfoObj for chaining
            return datainfoObj;
    });
    

    现在您可以从finalPromise链接将数据放在$scope

    finalPromise.then ( function onFulfulled (datainfo) {
        $scope.dataInfo = datainfo;
    }).catch (function onRejection (error) {
        console.log("finalPromise rejected");
        console.log(error.key);
        console.log(error.error);
    });
    

    请注意,$q.all没有弹性。如果任何一个 Promise 被拒绝,$q.all 将在第一次被拒绝时被拒绝。

    有关链接承诺的更多信息,请参阅AngularJS $q Service API Reference -- chaining promises

    【讨论】:

      猜你喜欢
      • 2019-05-03
      • 2016-06-25
      • 1970-01-01
      • 2016-08-19
      • 2016-08-20
      • 2016-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多