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

发布于 2024-10-14 21:58:32 字数 1066 浏览 3 评论 0原文

我有一个与单击处理程序绑定的按钮——它会进行一个或多个 AJAX 调用,具体取决于数组中有多少项。我使用 blockUI jquery 插件 在进行 ajax 调用时显示一条消息,然后我显示结果,并通过调用 $.unblockUI(); 删除 blockUI 消息。

问题:由于某种原因,无论我希望 ajaxCall 函数执行多少次,在第一个 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;
});

是否有解释为什么即使循环尚未完成,循环后的代码也会执行?任何帮助表示赞赏!谢谢。

I have a button tied to a click handler -- which makes one or more AJAX calls, depending on how many items are in an array. I use the blockUI jquery plugin to show a message while the ajax call(s) are being made, then I show the results, and remove the blockUI message by calling $.unblockUI();.

Problem: For some reason, no matter how many times I want the ajaxCall function to execute, after the FIRST ajax call completes, the messaging is removed even though the loop still continues to execute, and the results display correctly in the #results div. I want the full number of loop iterations to complete before removing the messaging, but it seems like its not executing sequentially. Here is the code in question:

$("#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;
});

Is there an explanation for why the code AFTER the loop is executing even though the loop isn't complete yet? Any help it appreciated! Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梨涡少年 2024-10-21 21:58:32
 ajaxCall(myArray[i]);

异步完成的,因此该方法在循环内触发,但执行将花费更多时间,因此在其余部分之后结束代码完成。

在这篇文章中找到了处理这种行为的一个好方法:异步方法队列JavaScript 中的链接

 ajaxCall(myArray[i]);

is done asynchronous so the method is fired within the loop, but the execution will take a little more time, thus ending after the rest of the code is finished.

an nice way of dealing with this kind of behaviour is found in this article: Asynchronous method queue chaining in JavaScript

苍白女子 2024-10-21 21:58:32

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

我能想到的解决此问题的一种可能方法是创建一个计数器变量,该变量在每次调用 ajaxCall() 时都会增加,并在每个完整处理程序中减少(XHR 就绪状态) 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();  
    }
}

Whatever ajaxCall() does, if it creates an XMLHttpRequest asyncronously, this is the correct behavior. An Ajax request is default non-blocking, I guess that is the reason why your code after your loop is executed immediately.

One possible way I can think of to solve this is, to create a counter variable, which increases on each call from ajaxCall() and decreases in each complete handler (XHR readystate 4). When that counter comes to zero, you should execute your code after the loop.

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();  
    }
}
魔法唧唧 2024-10-21 21:58:32

我猜 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 */
        }
    });
}

I'm guessing that ajaxCall is async? This will cause the code to not block on the loop, essentially completing the loop quickly and then progressing on.

What you can do is provide a callback function with a counter to check if all the ajax calls are complete.

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 */
        }
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文