Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Angular中,如何等待完成异步调用,然后转到foreach中的下一个对象?_Javascript_Angularjs - Fatal编程技术网

Javascript 在Angular中,如何等待完成异步调用,然后转到foreach中的下一个对象?

Javascript 在Angular中,如何等待完成异步调用,然后转到foreach中的下一个对象?,javascript,angularjs,Javascript,Angularjs,我在angular.forEach中遇到了一个关于angular异步调用的问题 如何等待嵌套异步调用完成,然后转到下一个foreach对象 下面是一个概念示例 假设我将临时代码为120012011202的记录插入数据库 现在我发现问题的症结是首先以1200完成每个循环,然后通过工厂创建成员,所以3个记录的临时代码是1200、1200、1200。 如何以正确的循环顺序进行修复 我想序列是 //1200 对于$scope.xyzList->getTempCode->createMember->upd

我在angular.forEach中遇到了一个关于angular异步调用的问题

如何等待嵌套异步调用完成,然后转到下一个foreach对象

下面是一个概念示例

假设我将临时代码为120012011202的记录插入数据库

现在我发现问题的症结是首先以1200完成每个循环,然后通过工厂创建成员,所以3个记录的临时代码是1200、1200、1200。 如何以正确的循环顺序进行修复

我想序列是

//1200 对于$scope.xyzList->getTempCode->createMember->updateTempCode中的每一个1

//1201 对于$scope.xyzList->getTempCode->createMember->updateTempCode中的每2个

//1202 对于$scope.xyzList->getTempCode->createMember->updateTempCode中的每3个

示例概念代码如下所示

假设$scope.xyzList对象列表有3个对象

var data = {"code": "null"};

angular.forEach($scope.xyzList, function(v, k){
    $http({
        method: 'POST',
        url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
        data: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    }).then(function(obj) {
       $scope.createMember(obj, v);
    }
})

$scope.createMember = function(obj, listVal) {
    var currentCode = obj;
    var cdata = {"code": currentCode};
    var memberView = New MemberView();
    memberView.code = obj;
    memberView.name = listVal.name;

    $http({
        method: 'POST',
        url: 'http://xxxx.com/checkCodeExist',
        data: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    }).then(function(rs) {
       if (rs.code == null) {
          xxxxFactory.createMember($rootScope.global.systemObj, memberView)
              .then(function(result){
                  $http({
                      method: 'POST',
                      url: 'http://xxxx.com/updateTempCode', // Temp code + 1
                      data: JSON.stringify(cdata),
                      headers: {'Content-Type': 'application/json'}
                  })
              })
       }
    }
}

当需要等待异步进程完成时,可以使用递归函数代替forEach循环。在这种情况下,类似这样的情况:

  function handleListItem(list, idx) {
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
      data: JSON.stringify(data)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(function (obj) {
        $scope.createMember(obj, list[idx], function () {
            var nextItem = list[++idx]
            if (nextItem) handleListItem(list, idx)
          }
        });
    }
  }
  $scope.createMember = function (obj, listVal, next) {
    // all of your code until here
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/updateTempCode', // Temp code + 1
      data: JSON.stringify(cdata)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(next)
  }
现在您的createMember函数需要将匿名函数作为其第三个参数,并在完成所有操作后调用该函数,如下所示:

  function handleListItem(list, idx) {
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
      data: JSON.stringify(data)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(function (obj) {
        $scope.createMember(obj, list[idx], function () {
            var nextItem = list[++idx]
            if (nextItem) handleListItem(list, idx)
          }
        });
    }
  }
  $scope.createMember = function (obj, listVal, next) {
    // all of your code until here
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/updateTempCode', // Temp code + 1
      data: JSON.stringify(cdata)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(next)
  }
最后,用列表和0索引作为参数调用该函数,开始所有操作

  handleListItem($scope.xyzlist, 0)

当需要等待异步进程完成时,可以使用递归函数代替forEach循环。在这种情况下,类似这样的情况:

  function handleListItem(list, idx) {
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
      data: JSON.stringify(data)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(function (obj) {
        $scope.createMember(obj, list[idx], function () {
            var nextItem = list[++idx]
            if (nextItem) handleListItem(list, idx)
          }
        });
    }
  }
  $scope.createMember = function (obj, listVal, next) {
    // all of your code until here
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/updateTempCode', // Temp code + 1
      data: JSON.stringify(cdata)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(next)
  }
现在您的createMember函数需要将匿名函数作为其第三个参数,并在完成所有操作后调用该函数,如下所示:

  function handleListItem(list, idx) {
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
      data: JSON.stringify(data)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(function (obj) {
        $scope.createMember(obj, list[idx], function () {
            var nextItem = list[++idx]
            if (nextItem) handleListItem(list, idx)
          }
        });
    }
  }
  $scope.createMember = function (obj, listVal, next) {
    // all of your code until here
    $http({
      method: 'POST'
      , url: 'http://xxxx.com/updateTempCode', // Temp code + 1
      data: JSON.stringify(cdata)
      , headers: {
        'Content-Type': 'application/json'
      }
    }).then(next)
  }
最后,用列表和0索引作为参数调用该函数,开始所有操作

  handleListItem($scope.xyzlist, 0)
您可以使用来在回调中持久化您的值。这样,您就不需要等待异步调用完成。例如:

function callbackCreator(val) {
    return function(obj) {
        $scope.createMember(obj, val);
    }
}

angular.forEach($scope.xyzList, function(v, k){
    var cb = callbackCreator(v);
    $http({
        method: 'POST',
        url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
        data: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    }).then(cb);
您可以使用来在回调中持久化您的值。这样,您就不需要等待异步调用完成。例如:

function callbackCreator(val) {
    return function(obj) {
        $scope.createMember(obj, val);
    }
}

angular.forEach($scope.xyzList, function(v, k){
    var cb = callbackCreator(v);
    $http({
        method: 'POST',
        url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
        data: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    }).then(cb);

使用es6
let
。让我们定义循环的作用域,这样你的循环就不会进入竞争条件,因为迭代器在每个循环中都有自己的作用域。只需小心,因为
for(obj中的var键)
会迭代原型:

var myObj = $scope.xyzList;
for (let key in myObj) {
  if (myObj.hasOwnproperty(key)) {
    let v = myObj[key];
    $http({
        method: 'POST',
        url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
        data: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    }).then(function(obj) {
       $scope.createMember(obj, v);
    }
  }
}

简单干净。希望有帮助。

使用es6
let
。让我们定义循环的作用域,这样你的循环就不会进入竞争条件,因为迭代器在每个循环中都有自己的作用域。只需小心,因为
for(obj中的var键)
会迭代原型:

var myObj = $scope.xyzList;
for (let key in myObj) {
  if (myObj.hasOwnproperty(key)) {
    let v = myObj[key];
    $http({
        method: 'POST',
        url: 'http://xxxx.com/getTempCode', // for example temp code: 1200
        data: JSON.stringify(data),
        headers: {'Content-Type': 'application/json'}
    }).then(function(obj) {
       $scope.createMember(obj, v);
    }
  }
}
简单干净。希望能有帮助