在foreach循环中调用javascript函数,等待回复?

时间:2011-09-16 21:39:32

标签: javascript ajax function loops

我对如何解决这个问题感到有些困惑。 我有一个函数updateDate(id),它使用传入的ID更新数据库中的特定行。这个函数对PHP脚本进行AJAX调用,运行需要一些时间。

然后我有另一个名为updateDates()的函数,它对另一个PHP脚本进行AJAX调用以获取需要更新的所有ID,然后循环遍历这些并使用循环中的当前ID调用updateDate(id)。

问题是循环在继续循环之前似乎没有等待来自updateDate(id)的响应,因此它同时创建了类似于2398572375的AJAX调用并且它会出错。

如何让循环在继续之前等待updateDate(id)的响应?

当AJAX调用的readyState为4时(意味着响应完成时),我尝试执行以下操作时,

updateDate(id)返回true:

if( updateDate( id ) ) { Do something. }

没有帮助。 有关于此的任何想法吗?

编辑:这是一些要求的代码。

updateDates():

                function updateDates()
                {

                    ids = new XMLHttpRequest();

                    ids.open( "GET", "<?php echo anchor("index.php/main/ajax/getIdsToUpdate"); ?>", true );
                    ids.onreadystatechange = function() {

                        if( ids.readyState == 4 )
                        {

                            var response = $.evalJSON( ids.responseText );
                            if( response.type == 1 )
                            {

                                $.each( response.message, function( index, value ) {

                                    if( value != '' )
                                    {

                                        if( updateDate( value ) )
                                            alert('Checked: ' + value);

                                    }

                                });

                            }

                        }

                    }

                    ids.send(null);

                }

updateDate(id):

                function updateDate( id )
                {

                    req = new XMLHttpRequest();
                    req.open("GET", "<?php echo anchor("index.php/main/ajax/updateDate/"); ?>" + id, true);

                    req.onreadystatechange = function() {

                        if( req.readyState == 4 ) 
                        {

                            var value = $.evalJSON( req.responseText );

                            // Updating a DIV on the site..

                            return true;

                        }

                    }
                    req.send(null);

                }

5 个答案:

答案 0 :(得分:2)

您没有显示很多代码或者您正在使用什么来进行ajax调用,但是您可以执行类似这样的伪代码,在上一个代码成功的情况下启动下一个ajax调用:

var idArray = [];   // suppose this is an array of ids that you want to update with individual ajax calls.

function updateNextId(list, index) {
    if (index < (list.length -  1)) {
        ++index;
        var id = idArray[index]
        ajax(parmss, function() {
            // success handler
            updateNextId(list, index);
        });
    }
}

更好的解决方案是在一次ajax调用中发送所有ID,并让服务器只处理多个ID。

答案 1 :(得分:1)

我认为诀窍是定义一个在AJAX函数完成时调用的回调,然后从那里递归调用updateDates函数。

在伪代码中:

function updateDates(items) {
    current_id = items[0];
    updateDate(current_id, oncomplete: function() {
        next_items = everything_but_current_item(items, current_id)
        updateDates(next_items)
    });
}

在一定量的递归后你可能会出现堆栈溢出,但这是我想到的最简单的实现方式。

答案 2 :(得分:1)

尝试使用jQuery循环方法.each(),jQuery $.ajax()和回调函数:

$('your element selection').each(function(){
  var thisElement=this;
  $.ajax(url,{
    success:function(data, textStatus, jqXHR){
      //do something to 'thisElement' element with 'data'
    } 
  });
});

我同意之前的海报,即使用多个ID的单个AJAX调用更好。

答案 3 :(得分:1)

有两种很好的方法可以在不影响同步(和锁定)UI的情况下完成此任务。

:一种。创建批量更新PHP脚本

这个很容易。扩展您的PHP脚本,以便它可以获取ID和日期列表,而不是一次只有一个。这是最高性能和最佳解决方案。

<强> B中。转换为队列

您应该将updateDates()转换为出列函数。这就是:

每次调用updateDates()时,它都会弹出您需要更新的ID数组的第一个元素,调用ajax函数,然后将updateDates设置为Ajax调用的回调。

伪代码/粗略草图:

function updateDates() {
    if(allDates.length == 0) return;

    var data = allDates.unshift();
    $.post('/save.php', { 'id': data.id, 'date': data.date }, updateDates);
}

答案 4 :(得分:0)

AJAX代表异步 Javascript和XML。这意味着它不会在继续之前等待响应。如果您希望它在继续之前等待,请改为synchronous