jQuery等待$.each执行完毕

5

嗨,我有一个困扰了我很长时间的大问题,大多数时候我都能够避免它,但现在别无选择。下面是一个函数,当执行时,会为每个选中的复选框发送一个post请求。我需要它等待$.each完成后再刷新页面。我已经在每个回调函数中使用location.reload和在$.each之外测试了刷新页面。如果将其移动到$.each之后(仍然在.click内),则只处理10个选择框中的7-8个并且处理3-4个。我需要它等待$.each完成后再刷新页面。有没有办法做到这一点?

$('button.moveToTable').click(function(event){
            $("input:checked").each(function(){
                $.post('/table/move-to-table',
                {orderID: $(this).val(),
                    tableID: $('#moveToTableID').val()
                },
                function(data){
                    location.reload();
                });
            });
            //location.reload();
        });
3个回答

6

一种简单的方法是将元素数量存储在全局范围内并进行减法运算。当最后一个元素完成请求时,它将重新加载。请注意,如果某些请求返回错误,则会失败,您还必须处理错误事件,并减去 window.Remaining。两次或更多点击也可能破坏此方法。

window.Remaining = 0;
$('button.moveToTable').click(function(event){
    window.Remaining = $("input:checked").length;
    $("input:checked").each(function(){
        $.post('/table/move-to-table',
        {orderID: $(this).val(),
            tableID: $('#moveToTableID').val()
        },
        function(data){
            --window.Remaining;
            if (window.Remaining == 0)
                window.location.reload();
        });
    });
    //location.reload();
});

1
使用 length 属性的想法很好。你可以通过这样做来避免两次运行选择器:window.Remaining = $('input:checked').each(function() { ... }).length。 :o) - user113716
只是一个小提示:为什么要将它放在 window 下面呢?这样在局部作用域中同样有效。没必要污染全局命名空间。 - Chris Broadfoot

5

不确定这是否是最佳解决方案,但一个想法是为每个请求发送增加一个计数,然后在请求返回时将其减少。

使用计数作为标志来确定是否应该触发reload()

类似以下内容:

var count = 0;

$('button.moveToTable').click(function(event){
            $("input:checked").each(function() { 
                count++; // Increment the counter for each request

                $.post('/table/move-to-table',
                {orderID: $(this).val(),
                    tableID: $('#moveToTableID').val()
                },
                function(data) { 
                    count--; // Decrement as the requests return

                        // Only reload if the count is 0
                    if( count === 0 )
                        location.reload();
                });
            });
        });

你可能需要一些代码来防止第二次点击事件发生。你可以使用同一个count变量来实现。如下所示:

if( count === 0 ) { 
    $("input:checked").each(func...

或者更好的想法可能是使用nsw1475提供的解决方案,如果您有这个选项,只需发送一个请求以获取所有复选框的值。


2
使用each()函数来生成一个json数组,存储哪些复选框已经被选中,这可能是更好、更高效、更无bug的方法,然后使用.post一起传递所有数据。完成后,调用页面刷新。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接