在完成之前,事情发生在我的for循环之外(javascript)

时间:2011-06-01 01:16:55

标签: javascript loops for-loop

我确信我以前见过这个并知道答案,但是12个小时之后......我的思绪完全糊涂了。

我有一个for循环,其中我试图连接到一个字符串,以便我可以完成字符串(从而完成一个漂亮的小表),我希望然后插入到我的html中并显示用户。 / p>

然而,我的函数结束时(在我的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');

}

如果您注意到,我想在最后关闭Table html,但是在我的for循环结束之前调用它,从而搞砸了我的字符串......

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

}

2 个答案:

答案 0 :(得分:2)

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

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个同步请求很多。

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

答案 1 :(得分:1)

$ .post是异步的,这意味着它会尽可能快地触发循环中的所有请求,然后退出循环。它不等待回应。当响应返回时,您的行函数将被调用...但到那时,所有帖子都已在途中发送。

在这里查看这个问题的答案...... How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

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