同步的.each与异步的.ajax

4

我正在阅读关于这个主题的所有其他问题,但似乎找不到适合我的代码的最佳选项。基本上,我有一个 .each 迭代器,它执行异步 ajax 函数。我需要这个函数是同步的,但又不会锁定浏览器,所以我选择不使用 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);
            }
        }
    });
});

2
为什么需要同步操作?按照定义,同步操作会“锁定”当前线程,因此不存在非阻塞的同步操作。您应该使用jQuery promises来确保在所有AJAX请求完成后执行某些操作。 - CodingIntrigue
1
看起来像是一个 XY 问题。那么为什么你需要这个同步呢?为什么不在服务器端设置一个脚本,一次性处理所有数据,然后只使用一个 ajax 调用呢?难道你的问题不仅仅是 success 回调中的 obj 吗?如果是的话,可以使用任何类型的闭包,例如,使用 ajax 请求的选项上下文设置为 obj,然后在 success 回调中使用 this - A. Wolff
1
你需要让Ajax请求按顺序运行还是同时并发运行? - iCollect.it Ltd
我需要它们按顺序运行,虽然在服务器端运行它们是我的备选方案,但我宁愿先尝试这种方法。 - alexhg11
1个回答

0

如果不使用 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();
            }
        }
    });
})();

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