同步 .each 和异步 .ajax

Posted

技术标签:

【中文标题】同步 .each 和异步 .ajax【英文标题】:synchronous .each with asynchronous .ajax 【发布时间】:2014-03-29 10:35:18 【问题描述】:

我正在阅读有关此主题的所有其他问题,但似乎无法为我的代码找到最佳选择。基本上我有一个执行异步 ajax 函数的 .each 迭代器。我需要在不锁定浏览器的情况下同步,所以我选择不使用async: false

代码如下:

$(".btn-timbrar").each(function(i, obj)
    $.ajax(
        type: 'POST',
        url: "Home?opt=Recibo_G", 
        data: id: $(obj).data("id"), p: pago,
        success: function(response)
            progress = progress + interval;
            $barra.find("#progreso-global").width(progress);
            $barra.find("#progreso-global").html(progress+"%"); 
            if(response.indexOf("timbrado con exito") != -1)               
                $(obj).parent().html('<a title="PDF" class="btn btn-recibo-info btn-mini" target="_blank" href="/ReciboVital/Home?opt=PDF&id='+$(obj).data("id")+'"><span class="glyphicon glyphicon-file"></span> PDF</a> <a title="XML" class="btn btn-recibo-info btn-mini" target="_blank" href="/ReciboVital/Home?opt=XML&id='+$(obj).data("id")+'"><span class="glyphicon glyphicon-download-alt"></span> XML</a> <a title="Enviar Correo" class="btn btn-recibo-info btn-mini btn-correo" href="/ReciboVital/Home?opt=Correo&='+$(obj).data("id")+'"><span class="glyphicon glyphicon-envelope"></span></a> <a title="Cancelar" class="btn btn-recibo-info btn-mini btn-correo" href="/ReciboVital/Home?opt=Cancelar&id='+$(obj).data("id")+'"><span class="glyphicon glyphicon-remove"></span></a>');
                $("#example thead th:eq(5)").width(150);
            
        
    );
);

【问题讨论】:

为什么需要同步?根据定义,同步操作“锁定”当前线程,因此不存在非阻塞同步操作。您应该使用 jQuery 承诺确保在所有 AJAX 请求完成后执行某些操作 看起来是 XY 问题。那么为什么你需要它是同步的呢?为什么不设置一个脚本服务器端来一次处理所有数据,然后只使用一个 ajax 调用?您的问题不只是因为obj 成功回调吗?如果是,请使用任何类型的闭包,例如,使用设置为 obj 的 ajax 请求的选项上下文,然后在成功回调中使用 this 问。您需要 Ajax 请求按顺序运行还是全部并行运行? 我需要它们按顺序运行,在服务器端运行它们是我的替代方法,但我宁愿先尝试一下。 【参考方案1】:

不使用async: false 的唯一方法是使用回调而不是.each() 循环。例如:

var buttons = $(".btn-timbrar");

(function nextButton() 
    var obj = [].pop.call(buttons);
    $.ajax(
        type: 'POST',
        url: "Home?opt=Recibo_G", 
        data: id: $(obj).data("id"), p: pago,
        success: function(response)
            progress = progress + interval;
            $barra.find("#progreso-global").width(progress);
            $barra.find("#progreso-global").html(progress+"%"); 
            if(response.indexOf("timbrado con exito") != -1)               
                $(obj).parent().html('<a title="PDF" class="btn btn-recibo-info btn-mini" target="_blank" href="/ReciboVital/Home?opt=PDF&id='+$(obj).data("id")+'"><span class="glyphicon glyphicon-file"></span> PDF</a> <a title="XML" class="btn btn-recibo-info btn-mini" target="_blank" href="/ReciboVital/Home?opt=XML&id='+$(obj).data("id")+'"><span class="glyphicon glyphicon-download-alt"></span> XML</a> <a title="Enviar Correo" class="btn btn-recibo-info btn-mini btn-correo" href="/ReciboVital/Home?opt=Correo&='+$(obj).data("id")+'"><span class="glyphicon glyphicon-envelope"></span></a> <a title="Cancelar" class="btn btn-recibo-info btn-mini btn-correo" href="/ReciboVital/Home?opt=Cancelar&id='+$(obj).data("id")+'"><span class="glyphicon glyphicon-remove"></span></a>');
                $("#example thead th:eq(5)").width(150);
            
            if(buttons.length > 0)  
                nextButton();
            
        
    );
)();

【讨论】:

以上是关于同步 .each 和异步 .ajax的主要内容,如果未能解决你的问题,请参考以下文章

AJAX中同步和异步的区别和使用场景

Ajax同步和异步

js中请求数据的$post和$ajax区别(同步和异步问题)

ajax的同步和异步问题

ajax同步和异步的切换

Ajax同步异步的区别