Javascript 如何等待each循环中的AJAX调用完成,然后在没有ASYNC的情况下继续:FALSE

Javascript 如何等待each循环中的AJAX调用完成,然后在没有ASYNC的情况下继续:FALSE,javascript,jquery,ajax,Javascript,Jquery,Ajax,我目前已经设置了一组从AJAX到PHP的函数,用于处理页面上的许多项。基本上,代码将一系列任务插入数据库,然后根据新创建的任务ID将供应插入数据库。然而,它90%的时间都能工作。有时似乎任务ID不是首先创建的,这不允许供应品使用这些ID插入数据库。是否有办法确保任务已插入,然后为该ID插入所有耗材,然后转到下一个。最后,当一切都完成时,我想重定向到一个新的页面,再次将其放在供应部分的最后一个成功调用中,但它会重定向到第一个循环。这一过程通常会产生大约5个任务,每个任务有12个补给。我正在读一篇关

我目前已经设置了一组从AJAX到PHP的函数,用于处理页面上的许多项。基本上,代码将一系列任务插入数据库,然后根据新创建的任务ID将供应插入数据库。然而,它90%的时间都能工作。有时似乎任务ID不是首先创建的,这不允许供应品使用这些ID插入数据库。是否有办法确保任务已插入,然后为该ID插入所有耗材,然后转到下一个。最后,当一切都完成时,我想重定向到一个新的页面,再次将其放在供应部分的最后一个成功调用中,但它会重定向到第一个循环。这一过程通常会产生大约5个任务,每个任务有12个补给。我正在读一篇关于<代码>$的文章。当循环时,它无法工作。注意:在测试ajax调用是否正确提交后,发现其中一些调用上的一个字段为空,而DB出现了问题。因此,下面的计数器方法是有效的

$(document).on("click", "#submitTasks", function(e) {
    e.preventDefault();
    var tasks = $('#tasks').find('.box');
    var project_id = $('#project_id').val();
    tasks.each(function() {
        var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr');
        var task_definition_id = $(this).find('.task_definition_id').val();
        var labor_type_id = $(this).find('.laborAmount').children('option:selected').val();
        var task_status_id = 1;
        var qty_labor = $(this).find('.laborQty').val();
        var amount_labor = $(this).find('.laborTotal').val();
        var amount_materials = $(this).find('.matTotal').val();
        var amount_gst = $(this).find('.gstTotal').val();
        amount_materials = +amount_materials + +amount_gst;
        amount_materials = amount_materials.toFixed(2);
        var active = 1;
        //console.log(div)
        var task = {
            project_id : project_id,
            task_definition_id : task_definition_id,
            labor_type_id : labor_type_id,
            task_status_id : task_status_id,
            qty_labor : qty_labor,
            amount_labor : amount_labor,
            amount_materials : amount_materials,
            active : active
        };
        saveTasks(task, trs, project_id);
    });
});
function saveTasks(task, trs, project_id) {
    $.ajax({
        type : "POST",
        url : "<?php echo base_url(); ?>" + "mgmt/project/saveTasks",
        data : task,
        dataType : "json",
        cache : "false",
        success : function(data) {
            trs.each(function() {
                var total = $(this).find('input[name="calculatedCost"]').val();
                if (total != 'n/a') {
                    var task_id = data;
                    var supply_id = $(this).find('.suppliesPicker').children('option:selected').val();
                    var task_requirement_id = $(this).find('td:first-child').data('id');
                    var qty = $(this).find('input[name="calculatedQty"]').val();
                    var cost_per = $(this).find('.costPicker').val();
                    var delivery_cost = $(this).find('input[name="transport"]').val();

                    var notes = '';
                    var qty_actual = '';
                    var active = 1;
                    var taskSupply = {
                        task_id : task_id,
                        supply_id : supply_id,
                        task_requirement_id : task_requirement_id,
                        qty : qty,
                        cost_per : cost_per,
                        delivery_cost : delivery_cost,
                        total : total,
                        notes : notes,
                        qty_actual : qty_actual,
                        active : active
                    };
                    saveTaskSupplies(taskSupply);
                    console.log(taskSupply);
                }
            });
        }
    });
}

function saveTaskSupplies(taskSupply) {
    $.ajax({
        type : "POST",
        url : "<?php echo base_url(); ?>" + "mgmt/project/saveTaskSupplies",
        data : taskSupply,
        dataType : "json",
        cache : "false",
        success : function(data) {
            ***** I WANT TO REDIRECT TO A NEW PAGE WHEN THE LAST ONE OF THESE COMPLETES ******
        }
    });
}    
$(文档)。在(“单击”上,“提交任务”,函数(e){
e、 预防默认值();
var tasks=$(“#tasks”).find(“.box”);
var project_id=$('#project_id').val();
任务。每个(函数(){
var trs=$(this).find('.reqTables').find('.table').find('tbody').find('tr');
var task_definition_id=$(this).find('.task_definition_id').val();
var labor_type_id=$(this).find('.laborarmount').children('option:selected').val();
var任务\状态\ id=1;
var qty_labor=$(this.find('.laborQty').val();
var amount_labor=$(this.find('.laboratortotal').val();
var amount_materials=$(this.find('.matTotal').val();
var amount_gst=$(this.find('.gstTotal').val();
物料金额=+物料金额++商品及服务税金额;
金额\材料=金额\材料。固定(2);
var-active=1;
//控制台日志(div)
变量任务={
项目id:项目id,
任务定义标识:任务定义标识,
人工类型标识:人工类型标识,
任务状态标识:任务状态标识,
人工数量:人工数量,
劳动力数量:劳动力数量,
金额\材料:金额\材料,
活动:活动
};
保存任务(任务、trs、项目id);
});
});
功能保存任务(任务、trs、项目id){
$.ajax({
类型:“POST”,
url:“+”管理/项目/保存任务“,
数据:任务,
数据类型:“json”,
缓存:“false”,
成功:功能(数据){
trs.each(函数(){
var total=$(this.find('input[name=“calculatedCost”]').val();
如果(总计!=“不适用”){
var task_id=数据;
var supply_id=$(this).find('.suppliesPicker').children('option:selected').val();
var task_requirement_id=$(this).find('td:first child').data('id');
var qty=$(this.find('input[name=“calculatedQty”]').val();
var cost_per=$(this.find('.costPicker').val();
var delivery_cost=$(this).find('input[name=“transport”]”)。val();
var注释=“”;
var数量_实际值=“”;
var-active=1;
var taskSupply={
任务id:任务id,
供应标识:供应标识,
任务需求标识:任务需求标识,
数量:数量,,
每个成本:每个成本,
交货成本:交货成本,
总计:总计,
注:注:,
实际数量:实际数量,
活动:活动
};
saveTaskSupplies(taskSupply);
控制台日志(taskSupply);
}
});
}
});
}
功能saveTaskSupplies(taskSupply){
$.ajax({
类型:“POST”,
url:“+”管理/project/saveTaskSupplies”,
数据:taskSupply,
数据类型:“json”,
缓存:“false”,
成功:功能(数据){
*****我想在最后一个页面完成时重定向到新页面******
}
});
}    

关于第一个问题,通过研究您的代码,我看不出原因。只有在
saveTasks()
成功执行时,才能执行
saveTaskSupplies()
,因此应该已经创建了
task\u id

但是,我会从后端考虑另一个可能的问题,在
saveTasks()
中的Ajax
success
函数中,假设PHP脚本总是成功执行并返回
任务id
。您的PHP脚本是否有可能出现问题,并且在某些情况下没有创建
task\u id

对于第二个问题,有几种方法,@Seth建议您可以使用,或者您可以创建一个全局计数器来跟踪
saveTaskSupplies()
是否是最后一种方法。请注意,您应该在触发Ajax请求之前计算TR的总长度,否则,您可能会在所有任务完成之前计算不好的总长度并进行重定向。如果它是最后一个,它将在成功的Ajax调用后重定向

// create a global counter
var counter = 0, 
    trl = 0;
$(document).on("click", "#submitTasks", function(e) {
    ...
    var trList = [];
    tasks.each(function() {
        // calculate the length of total task before actually firing the Ajax Request
        var trs = $(this).find('.reqTables').find('.table').find('tbody').find('tr');
        // keep a copy of the trs so the next each loop does not have to find it again
        trList.push(trs);
        trl += trs.length;
    });
    tasks.each(function() {
        // get the trs of current iteration we have found in last loop
        var trs = trList.shift();
        ...
        saveTasks(task, trs, project_id);
    });
});

function saveTasks(task, trs, project_id) {
    $.ajax({
        ...
        success : function(data) {
            trs.each(function() {
                ...
                saveTaskSupplies(taskSupply);
            }
        }
    });
}

function saveTaskSupplies(taskSupply) {
    $.ajax({
        ...
        success : function(data) {
            // check if the counter exceed the length of trs
            if (++counter == trl) { 
                location.href = 'place you want to go'; 
            }
        }
    });
}

另一方面,对于您的任务,我还建议将数据插入的责任转移到PHP后端,因此您需要做的就是将任务信息和任务提供立即传递给单个PHP脚本。这种方法允许使用事务来确保所有数据插入成功,否则所有数据插入都会失败。

下面是使用您提供的代码的直接解决方案。英国广播公司
var allPromises;

$(document).on("click", "#submitTasks", function(e) {
    //...
    var tasks = $('#tasks').find('.box');

    allPromises = [];

    tasks.each(function() {
        //.. somehow getTask
        var req = saveTasks(task, trs, project_id);
        allPromises.push(req);
    });

    $.when.apply(null, allPromises).done(function(){
        // Do your things here,
        // All save functions have done.
    });
});

function saveTasks(task, trs, project_id) {
    return $.ajax({
        // ,,, your codes
        success : function(data) {
            // ...
            trs.each(function() {
                // ... Somehow get taskSupply
                var req = saveTaskSupplies(taskSupply);
                allPromises.push(req);
            }
        }
    });
}

function saveTaskSupplies(taskSupply) {
    return $.ajax({
        // ... bla bla bla
        success : function(data) {
            // Whatever..
        }
    });
}