2012-02-19 51 views
0

我有JavaScript/jQuery代碼,它獲取信息並使用while/for循環的混合將其更新到數據庫中。在提取時,我有一個div,顯示正在進行的最新進度日誌。在Firefox中,隨着腳本運行,它會在它應該同時更新div。在谷歌瀏覽器中,它運行整個循環,保留日誌,並只輸出它,直到腳本完成運行。任何人都知道爲什麼會發生這種情況?爲什麼Javascript輸出在Google Chrome中被阻止?

這裏是我的代碼:

$(document).ready(function() { 
    add_text("test"); 

    var array_length = num_sets; 

    for(var i = 0; i < array_length; i = i + 1) { 
     var setId = sets[i]['id']; 
     var setName = sets[i]['name']; 
     var setLinkName = sets[i]['link']; 
     var setNumCards = sets[i]['num_cards']; 

     add_text("Beginning to fetch set \"" + setName + "\""); 
     add_text("Found " + setNumCards + " total cards."); 

     while(ii < setNumCards) { 
      var card_name = sets[i]['cards'][ii]['name']; 
      var card_link = sets[i]['cards'][ii]['link']; 
      add_text("Fetching card " + sets[i]['cards'][ii]['name']); 

      fetch_card(sets[i]['cards'][ii]['link'], setId); 
     } 

    } 
}); 

add_text功能:

function add_text(text) { 
    $("#status_text").append("<br />" + text); 
} 

fetch_card功能:

function fetch_card(card_link, set_id) 
{ 
    $.ajax({ 
     url: "fetch_card.php?link=" + card_link + "&set_id=" + set_id, 
     context: document.body, 
     async: false, 
     success: function(){ 
     ii = ii + 1; 
     } 
    }); 
} 
+0

什麼是'add_text()'的代碼? – LordZardeck 2012-02-19 00:03:47

+0

function add_text(text){ $(「#status_text」)。append(「
」+ text); } – user1218595 2012-02-19 00:08:51

+1

如果代碼是同步的(看起來像),通常瀏覽器將不會重繪,直到當前的同步代碼完成。如果它是同步的,我很驚訝Firefox在完成之前重新繪製。 – 2012-02-19 00:10:27

回答

4

使用同步Ajax調用(這一般不是很理想) 。瀏覽器可以阻止所有活動,直到ajax調用完成。瀏覽器在同步ajax調用期間是否更新屏幕取決於瀏覽器。

如果將代碼重寫爲僅使用異步ajax,則代碼會更好。它需要更多的工作才能正確構建代碼以使用異步ajax調用,但瀏覽器在異步ajax調用期間仍然完全響應。

我不完全確定你在原始實現中如何使用ii變量(因爲它沒有在你包含的代碼中聲明或初始化),但這是你可以使用的一般結構。它使用傳統的for循環來收集數組中所需的所有數據,然後在該數據上一次調用ajax函數。這是我不清楚你是如何真正做什麼用返回阿賈克斯信息,但也許,只是有些事情不是你這裏包括:

$(document).ready(function() { 
    add_text("test"); 

    var array_length = num_sets; 
    var fetchData = []; 
    var fetchIndex = 0; 

    for(var i = 0; i < array_length; i++) { 
     var setId = sets[i]['id']; 
     var setName = sets[i]['name']; 
     var setLinkName = sets[i]['link']; 
     var setNumCards = sets[i]['num_cards']; 

     add_text("Beginning to fetch set \"" + setName + "\""); 
     add_text("Found " + setNumCards + " total cards."); 
     for (var ii = 0; ii < setNumCards; ii++) { 
      var card_name = sets[i]['cards'][ii]['name']; 
      var card_link = sets[i]['cards'][ii]['link']; 
      add_text("Fetching card " + sets[i]['cards'][ii]['name']); 
      fetchData.push({link: sets[i]['cards'][ii]['link'], id: setId}); 
     } 
    } 

    function next() { 
     if (fetchIndex < fetchData.length) { 
      fetch_card(fetchData[fetchIndex].link, fetchData[fetchIndex].id, next); 
      fetchIndex++; 
     } 
    } 

    function fetch_card(card_link, set_id, successFn) { 
     $.ajax({ 
      url: "fetch_card.php?link=" + card_link + "&set_id=" + set_id, 
      context: document.body, 
      async: true, 
      success: successFn 
     }); 
    } 

    next(); 
}); 
+0

噢!現在有道理!謝謝。 – user1218595 2012-02-19 00:18:00

+0

但事情是,我需要一張卡來一次更新。如果我做異步ajax,它會立即執行所有這些操作。我需要它一次做一個。 有什麼辦法,我可以有一個for或while循環等待,直到Ajax函數完成(我的fetch_card函數)才移動到下一張卡? – user1218595 2012-02-19 00:19:45

+0

@ user1218595 - 正如我所說的,您需要重構您的代碼。運行一個ajax調用,然後在該調用的成功處理程序中,啓動下一個ajax調用,等等......您無法像現在那樣通過簡單的'for'循環來實現這一點。 – jfriend00 2012-02-19 00:20:47

相關問題