如何按顺序在多个记录的循环中运行API

时间:2017-09-15 06:03:47

标签: angularjs node.js

有一个HTML表,其中数据应该通过节点API来传递。

<table cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th>Row1</th>
            <th>Row2</th>
            <th>Row3</th>
            <th>Row4</th>
            <th>Row5</th>
            <th>Row6</th>
            <th>Row7</th>
            <th>Row8</th>
            <th>Row9</th>
            <th>Row10</th>
            <th>Row11</th>
            <th>Row12</th>
            <th>Row13</th>
            <th>Row14</th>
            <th>Row15</th>
            <th>Row16</th>
            <th>Row17</th>
            <th>Row18</th>
            <th>Row19</th>
            <th>Row20</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="row in array track by $index">
            <td>{{row.value1}}</td>
            <td>{{row.value2}}</td>
            <td>{{row.value3}}</td>
            <td>{{row.value4}}</td>
            <td>{{row.value5}}</td>
            <td>{{row.value6}}</td>
            <td>{{row.value7}}</td>
            <td>{{row.value8}}</td>
            <td>{{row.value9}}</td>
            <td>{{row.value10}}</td>
            <td>{{row.value11}}</td>
            <td>{{row.value12}}</td>
            <td>{{row.value13}}</td>
            <td>{{row.value14}}</td>
            <td>{{row.value15}}</td>
            <td>{{row.value16}}</td>
            <td>{{row.value17}}</td>
            <td>{{row.value18}}</td>
            <td>{{row.value19}}</td>
            <td>{{row.value20}}</td>
        </tr>
    </tbody>
</table>

我的角度指令代码: -

ApiServices.getArrayData(value).then(function (response) {
            scope.array = response.data; // This is an array of objects
            for (var i = 0; i < scope.array.length; i++) {
                ApiServices.getOtherDetails(scope.array[i].id).then(function (response) {
                    scope.array[i].value2 = response.data.value2;
                    scope.array[i].value3 = response.data.value3;
                    scope.array[i].value5 = response.data.value5;
                    scope.array[i].value8 = response.data.value8;
                    scope.array[i].value11 = response.data.value11;
                    scope.array[i].value12 = response.data.value12;
                    scope.array[i].value13 = response.data.value13;
                    scope.array[i].value18 = response.data.value18;
                    scope.array[i].value20 = response.data.value20;
                });
            }
})

在上面的代码中: - getArrayData API仅为某些行提供数据。对于其他行,我从getOtherDetails API中获取数据,该API从每个记录的scope.array [i] .id获取值。

我在这里遇到的问题是循环在我想要的流程中不起作用。它首先迭代for循环,然后循环内部API。所以数据只显示在一条记录中。

有没有什么方法可以按照我编码的方式制作循环流程。或者有没有其他方法来实现我在这里尝试做的事情。请建议任何解决方案。

2 个答案:

答案 0 :(得分:0)

您可以使用async.mapSeriesasync模块。 这将逐个执行您的项目,在最后回调时,您可以发送回复。

我只是给你一个简单的例子,它如何与setTimeout函数一起使用。 你将获得最终回调的结果

async.mapSeries([1,2,3,4],function(item,cb){
setTimeout(function(){
console.log(item);
},1000)
cb();
},function(err,result){
console.log(result)
})

答案 1 :(得分:0)

这里的问题与javascript关闭有关。由于回调是异步的,因此所有回调都将获得相同的i值。

const test = (callback) => {
setTimeout(callback, 1000)
}

const count = 3

//wrong
for(var i = 0; i < count; i++){

test(() => {
  	console.log("i: " + i)
  })
}

//right es5 - using ugly self-invoking function
for(var j = 0; j < count; j++){
(function(j){
	test(() => {
  		console.log("j: " + j)
  })
})(j);
}

//right es6
for( let k = 0; k < count; k++){

test(() => {
  	console.log("k: " + k)
  })
}

模拟和测试您的场景。

angular.module("app", []).controller("testController", function($scope, $q) {
  $scope.array = []
  //simulate api
  $scope.getArrayData = () => {
    const deferred = $q.defer();
    deferred.resolve([{
      id: 1
    }, {
      id: 2
    }, {
      id: 3
    }, {
      id: 4
    }, {
      id: 5
    }])
    return deferred.promise
  }

  //simulate api
  $scope.getOtherDetails = (id) => {
    const deferred = $q.defer();
    deferred.resolve({
      data: {
        id: id,
        value1: id + 'value1',
        value2: id + 'value2',
        value3: id + 'value3',
        value4: id + 'value4',
        value5: id + 'value5'
      }
    })
    return deferred.promise
  }

  $scope.render = () => {
    $scope.getArrayData().then((response) => {
      $scope.array = response
      for (let i = 0; i < response.length; i++) {
        $scope.getOtherDetails(response[i].id).then(response => {
          $scope.array[i].value1 = response.data.value1
          $scope.array[i].value2 = response.data.value2
          $scope.array[i].value3 = response.data.value3
          $scope.array[i].value4 = response.data.value4
          $scope.array[i].value5 = response.data.value5
        })
      }
    })
  }

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="testController">
    <button ng-click="render()" style="width:100px; height:30px;">render</button>
    <table cellpadding="0" cellspacing="0">
      <thead>
        <tr>
          <th>Row1</th>
          <th>Row2</th>
          <th>Row3</th>
          <th>Row4</th>
          <th>Row5</th>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="row in array track by $index">
          <td>{{row.value1}}</td>
          <td>{{row.value2}}</td>
          <td>{{row.value3}}</td>
          <td>{{row.value4}}</td>
          <td>{{row.value5}}</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>