事情在我的for循环完成之前就已经发生了(javascript)

Things are happening outside my for loop before its done (javascript)

本文关键字:发生了 javascript 我的 for 循环      更新时间:2023-09-26

我肯定以前见过这个,知道答案,但12个小时后。。。我的脑子一片混乱。

我有一个for循环,在这个循环中,我试图连接到一个字符串上,这样在我完成字符串之后(从而完成一个漂亮的小表),我希望插入到我的html中并向用户显示。

然而,函数末尾的东西(在for循环之后)在for循环之前被调用。。。。

function getEntries() {
$('#entryTotalsDiv').html('<img src="images/ajax-loader.gif" /> ... retrieving form totals.');
var entryTotalsTable = "<table id='entryTable' class='display' style='border:1px;'><thead><tr><th>Form Name</th><th>Hash</th><th>Entries</th></tr></thead>" +
        "<tbody>"
//Get rows ONE at a time.
var countNumber = 1;
for (var frm = 0; frm < numberOfForms; frm++) {
    $.post('ajax/getEntries.aspx',
    {
        'formNumber': frm
    },
    function (data) {
        entryTotalsTable += "<tr><td>" + data[0].formName + "</td><td>" + data[0].formHash + "</td><td>" + data[0].formEntryCount + "</td></tr>";
        //Now go and update the Form Retrieval div -- add 1 to the frm Number
        $('#formNamesDiv').html(countNumber + ' of ' + numberOfForms + ' retrieved.');
        countNumber++;            
    });
}
entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');

}

如果你注意到的话,我想在最后关闭Tablehtml,但这在我的for循环完成之前就被调用了,所以把我的字符串搞砸了。。。

entryTotalsTable += "</tbody></table>";
$('#entriesDiv').html(entryTotalsTable);
//Now bind the table to the DataTables JQ script
$('#entryTable').dataTable();
$('#entryTable').show('slow');

}

解决方案可以是将每个响应保存在数组中,并在每次回调中测试当前计数是否等于总计数。类似于:

var countNumber = 1,
    allData = [];
function runWhenFinished() {
    if(countNumber === numberOfForms) {
        var entryTotalsTable = "<table id='entryTable' class='display' style='border:1px;'><thead><tr><th>Form Name</th><th>Hash</th><th>Entries</th></tr></thead>" + "<tbody>";
        for(var i = 0, l = allData.length; i < l; i++) {
             entryTotalsTable += "<tr><td>" + allData[i].formName + "</td><td>" + allData[i].formHash + "</td><td>" + allData[i].formEntryCount + "</td></tr>";
        }
        entryTotalsTable += "</tbody></table>";
        $('#entriesDiv').html(entryTotalsTable);
        //Now bind the table to the DataTables JQ script
        $('#entryTable').dataTable();
        $('#entryTable').show('slow');
    }
}
for(var frm = 0; frm < numberOfForms; frm++) {
    (function(frm) {
        $.post('ajax/getEntries.aspx',{'formNumber': frm}, function (data) {
            allData[frm] = data[0];
            countNumber++;
            $('#formNamesDiv').html(countNumber + ' of ' + numberOfForms + ' retrieved.');
            runWhenFinished();
        });
    }(frm));
}

我相信这仍然可以改进,但你明白了。


如果你真的提出了70个请求,那么你可能无论如何都需要重新考虑你的策略。70个同时请求太多了。

例如,您可以发出一个请求,并证明应检索/更新的最小和最大数量/无论该方法在做什么。

$.post是异步的,这意味着它将以最快的速度触发循环中的所有请求,然后退出循环。它不需要等待回应。当响应返回时,您的行函数将被调用。。。但到那时,所有的帖子都已发送完毕。

请在此处查看此问题的答案。。。如何让jQuery执行同步而非异步Ajax请求?

您需要从$.post更改为$.ajax