【问题标题】:How can I get my code to wait till all the code in a loop executes before continuing?如何让我的代码等到循环中的所有代码执行后再继续?
【发布时间】:2012-08-20 08:09:19
【问题描述】:

我正在使用 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 调用开始,然后在完成 get 之前和 numSuccessful 变量更新之前继续发出警报。在测试运行中,我以“0 成功”而不是“4 成功”结束,因为警报执行得太快了。如何让代码等到所有完成后再继续?整个“each”语句是否有成功回调?

【问题讨论】:

  • 你可以使用jQuery.Callbacks.promise()——你熟悉这种JS吗?
  • $('#mySelector').each? ID 必须是唯一的,您的选择器只选择第一个 id 为 mySelector 的元素。
  • 我使用两个函数循环解决了一个类似的问题:一个外部计数器跟踪元素,将“每个”构造块的内容作为一个函数,完成后调用回调函数,以及如果计数器低于 nr 个元素,则回调再次执行第一个函数。
  • @undefined - 抱歉,这是一个错字。应该是$('.mySelector'),我会更新。
  • @m90 - 不,你能详细说明一下吗?

标签: jquery callback each


【解决方案1】:

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

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

通过执行此脚本将等到它得到响应。

【讨论】:

  • 谢谢,这行得通 - 你的代码中只有一个语法错误,你需要在 ajax 调用的主体周围加上花括号
【解决方案2】:

你可以使用递归函数,试试下面的:

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()

【讨论】:

  • 也许你的意思是.error(callback)而不是.error(callback())
【解决方案3】:

您可以使用$.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');
});​

【讨论】:

    【解决方案4】:
    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() 函数。并定义成功和失败回调。如果您需要帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 2019-09-23
      • 2022-11-25
      • 2014-12-14
      • 1970-01-01
      • 2022-11-25
      • 2019-08-16
      • 2021-08-10
      • 2020-06-14
      • 1970-01-01
      相关资源
      最近更新 更多