为什么我的javascript / jquery没有顺序执行?

时间:2011-01-31 18:28:53

标签: javascript loops jquery jquery-blockui

我有一个与点击处理程序绑定的按钮 - 根据数组中的项目数进行一次或多次AJAX调用。我使用blockUI jquery plugin在进行ajax调用时显示消息,然后显示结果,并通过调用$ .unblockUI();删除blockUI消息。

问题:由于某种原因,无论我希望ajaxCall函数执行多少次,在FIRST ajax调用完成后,即使循环仍然继续执行,消息也会被删除,并且结果在#results div中正确显示。我希望在删除消息传递之前完成完整数量的循环迭代,但似乎它没有按顺序执行。以下是有问题的代码:

$("#myButton").live("click", function(){
    $.blockUI({ message: '<img src="new_loader.gif" /><h2>Getting Config Files</h2><small>Please be patient.</small>',
            css: { 
            border: 'none', 
            padding: '15px', 
            backgroundColor: '#FFF', 
            '-webkit-border-radius': '10px', 
            '-moz-border-radius': '10px',  
            color: '#000' 
            } 
        }); 

    for (var i=0; i< myArray.length; i++)
        {
         ajaxCall(myArray[i]);
        }
    $("#results").show('slow');
    $.unblockUI();  
    return false;
});

是否有解释为什么循环执行后代码即使循环尚未完成?任何帮助它赞赏!感谢。

3 个答案:

答案 0 :(得分:4)

 ajaxCall(myArray[i]);

已完成异步,因此该方法在循环中触发,但执行将花费更多时间,因此在其余代码已经完成。

在本文中可以找到处理此类行为的好方法: Asynchronous method queue chaining in JavaScript

答案 1 :(得分:2)

无论ajaxCall()做什么,如果它异步创建XMLHttpRequest,这是正确的行为。 Ajax请求是默认的非阻塞,我想这就是为什么你的代码在你的循环被立即执行之后的原因。

我可以想到解决这个问题的一种可能方法是,创建一个计数器变量,它在ajaxCall()的每个调用中增加,在每个complete处理程序中减少(XHR readystate 4)。当该计数器变为零时,您应该在循环后执行代码。

function increase() {      // goes into your `ajaxCall()` or `beforeSend` callback
    mynamespace.requests++;
}

function decrease() {      // goes into your `complete` callbacks
    if(--mynamespace.requests) {
        $("#results").show('slow');
        $.unblockUI();  
    }
}

答案 2 :(得分:1)

我猜测ajaxCall是异步的吗?这将导致代码不会阻塞循环,基本上快速完成循环,然后继续进行。

您可以做的是提供一个带有计数器的回调函数,以检查所有ajax调用是否完整。

var count = arr.length - 1;
for(var i = 0; i < arr.length; i++)
{
    ajaxCall(arr[i], function () {
        if(--count == 0)
        {
            /* All AJAX calls complete, continue execution */
        }
    });
}