如何让代码等到循环中的所有代码执行后再继续?

时间:2012-08-20 08:09:20

标签: jquery callback each

我正在使用jquery each迭代一组html元素。在每次迭代中,我调用get。我想跟踪成功的获取并在结束时输出一个计数。

var numSuccessful = 0;
$('.mySelector').each(function(){
    $.get('/myCfc.cfc?method=doSomething&id=' + $(this).attr('id'), 
        function(data){
            numSuccessful++;
    });
});
alert(numSuccessful + ' successful');

此代码的问题在于每个方法都会启动所有get调用,然后在完成gets之前继续执行警报 - 并且在更新numSuccessful变量之前。在测试运行中,我最终得到“0成功”而不是“4成功”,因为警报执行得太快。如何才能让代码等到所有内容完成后再继续?整个“每个”声明是否有成功的回调?

4 个答案:

答案 0 :(得分:1)

您可以使用递归功能,尝试以下操作:

var num = 0;
var $ms = $('.mySelector');

function go() {
     $.get('/myCfc.cfc?method=doSomething&id='+$ms.eq(num).attr('id'), 
       function(data){
            num++;
            if ((num-1) == $ms.length) callback(); else go();
     }).error(callback)
}

function callback(){
  alert(num)
}

go()

答案 1 :(得分:1)

您可以使用$.ajax返回的承诺来设置灵活的回调队列,如下所示:

var requests = []; //Array containing all the ajax calls

for (var i = 0; i < 9; i++) {
    requests.push(
    $.ajax({
        url: '/echo/html', //this is because of jsfiddle.net
        type: 'post', //this one too
        success: function() {
           //whatever
        }
    }));
}

$.when.apply($, requests).then(function() { //.apply is needed as we want to pass an Array
  //called when all requests are done
}).fail(function(){ //this will be triggered when one of the requests fails
  //error handling can go here
});

请参阅 this working fiddle 并阅读 .when() and .then

在您的情况下,最终会:

var numSuccessful = 0;

var requests = $.makeArray($('.mySelector').map(function(){
    return $.ajax({
        url: '/myCfc.cfc?method=doSomething&id=' + this.id,
        type: 'GET'
    }).done(function(){
        numSuccessful++;
    });
}));

$.when.apply($, requests).then(function() {
    alert(numSuccessful + ' successful');
});​

答案 2 :(得分:1)

只需将$.get替换为$.ajax,并将async设置为false。

$.ajax({
    url : '/myCfc.cfc',
    data : { 'method' : 'doSomething' , 'id' : $(this).attr('id') },
    async : false,
    success : function(data){
       numSuccessful++;
    }
});

通过这样做,脚本将一直等到它得到响应。

答案 3 :(得分:0)

var numSuccessful = 0;
var totalSelectors = $('#mySelector').length;
$('#mySelector').each(function(){
  $.get('/myCfc.cfc?method=doSomething&id=' + $(this).attr('id'), 
  function(data){
    numSuccessful++;
    if(!totalSelectors--) doneSelectors();
  });
});

function doneSelectors() {
  alert(numSuccessful + ' successful');
}

注意:上述功能无法正常工作! $.get()不会通知错误,因此如果您收到任何错误,最终功能将永远不会运行。

相反,您需要将其转换为使用$.ajax()函数。并定义成功和失败回调。如果您需要帮助,请告诉我。