2012-06-28 97 views
1

我正在學習javascript和json,但我遇到了一些問題:我有一個腳本可以與json一起使用,但是我寫的內容的表現並不好。該代碼僅在我使用螢火蟲或其他工具一步一步地進行調試時才起作用,並且這使我認爲代碼的執行(或其中的一部分......創建表的那一部分,如您所見)需要瀏覽器停止了太多時間。JavaScript代碼的異步執行

的代碼是:

var arrayCarte = []; 
var arrayEntita = []; 
var arraycardbyuser = []; 

function displayArrayCards() { 
var richiestaEntity = new XMLHttpRequest(); 

richiestaEntity.onreadystatechange = function() { 
    if(richiestaEntity.readyState == 4) { 
     var objectentityjson = {}; 
     objectentityjson = JSON.parse(richiestaEntity.responseText); 

     arrayEntita = objectentityjson.cards; 
    } 
} 
richiestaEntity.open("GET", "danielericerca.json", true); 
richiestaEntity.send(null); 

for(i = 0; i < arrayEntita.length; i++) { 

    var vanityurla = arrayEntita[i].vanity_urls[0] + ".json"; 
    var urlrichiesta = "http://m.airpim.com/public/vurl/"; 

    var richiestaCards = new XMLHttpRequest(); 
    richiestaCards.onreadystatechange = function() { 
     if(richiestaCards.readyState == 4) { 
      var objectcardjson = {}; 
      objectcardjson = JSON.parse(richiestaCards.responseText); 


      for(j = 0; j < objectcardjson.cards.length; j++) 
      arrayCarte[j] = objectcardjson.cards[j].__guid__; //vettore che contiene i guid delle card 

      arraycardbyuser[i] = arrayCarte; 

      arrayCarte = []; 
     } 
    } 
    richiestaCards.open("GET", vanityurla, true); 
    richiestaCards.send(null); 
} 





var wrapper = document.getElementById('contenitoro'); 

wrapper.innerHTML = ""; 

var userTable = document.createElement('table'); 

for(u = 0; u < arrayEntita.length; u++) { 
    var userTr = document.createElement('tr'); 

    var userTdcard = document.createElement('td'); 
    var userTdinfo = document.createElement('td'); 

    var br = document.createElement('br'); 

    for(c = 0; c < arraycardbyuser[u].length; c++) { 
     var cardImg = document.createElement('img'); 
     cardImg.src = "http://www.airpim.com/png/public/card/" + arraycardbyuser[u][c] + "?width=292"; 
     cardImg.id = "immaginecard"; 
     userTdcard.appendChild(br); 
     userTdcard.appendChild(cardImg); 

    } 

    var userdivNome = document.createElement('div'); 
    userdivNome.id = "diverso"; 
    userTdinfo.appendChild(userdivNome); 

    var userdivVanity = document.createElement('div'); 
    userdivVanity.id = "diverso"; 
    userTdinfo.appendChild(userdivVanity); 

    var nome = "Nome: "; 
    var vanityurl = "Vanity Url: "; 
    userdivNome.innerHTML = nome + arrayEntita[u].__title__; 
    userdivVanity.innerHTML = vanityurl + arrayEntita[u].vanity_urls[0]; 

    userTr.appendChild(userTdcard); 
    userTr.appendChild(userTdinfo); 
    userTable.appendChild(userTr); 
} 

wrapper.appendChild(userTable); 
} 

的問題是,應該讓表中的代碼不等待與JSON文件的工作代碼的完整執行。我該如何解決它?如果可能的話,我寧願用簡單的東西來解決這個問題,而不用jQuery和回調(我是一個初學者)。

回答

1

你必須移動som代碼才能完成這項工作。首先,將其分解爲一些功能,然後更容易處理。我不知道它是否有效,但這個想法是,它首先加載arrayEntita。完成後,它將填充其他2個陣列。當最後一個數組被填滿時,它會建立表格。

var arrayCarte = []; 
var arrayEntita = []; 
var arraycardbyuser = []; 
function displayArrayCards() { 
    var richiestaEntity = new XMLHttpRequest(); 
     richiestaEntity.onreadystatechange = function() { 
      if (richiestaEntity.readyState == 4) { 
      var objectentityjson = {}; 
      objectentityjson = JSON.parse(richiestaEntity.responseText); 

       arrayEntita = objectentityjson.cards; 
       BuildArrayEntita(); 
      } 
     } 
     richiestaEntity.open("GET", "danielericerca.json", true); 
     richiestaEntity.send(null); 
    } 

    function BuildArrayEntita() { 
     for (i = 0; i < arrayEntita.length; i++) { 

      var vanityurla = arrayEntita[i].vanity_urls[0] + ".json"; 
      var urlrichiesta = "http://m.airpim.com/public/vurl/"; 

      var richiestaCards = new XMLHttpRequest(); 
      richiestaCards.onreadystatechange = function() { 
       if (richiestaCards.readyState == 4) { 
        var objectcardjson = {}; 
        objectcardjson = JSON.parse(richiestaCards.responseText); 


        for (j = 0; j < objectcardjson.cards.length; j++) 
         arrayCarte[j] = objectcardjson.cards[j].__guid__; //vettore che contiene i guid delle card 

        arraycardbyuser[i] = arrayCarte; 

        arrayCarte = []; 
        //If it is the last call to populate arraycardbyuser, build the table: 
        if (i + 1 == arrayEntita.length) 
         BuildTable(); 
       } 
      } 
      richiestaCards.open("GET", vanityurla, true); 
      richiestaCards.send(null); 
     } 
    } 



    function BuildTable() { 
     var wrapper = document.getElementById('contenitoro'); 

     wrapper.innerHTML = ""; 

     var userTable = document.createElement('table'); 

     for (u = 0; u < arrayEntita.length; u++) { 
      var userTr = document.createElement('tr'); 

      var userTdcard = document.createElement('td'); 
      var userTdinfo = document.createElement('td'); 

      var br = document.createElement('br'); 

      for (c = 0; c < arraycardbyuser[u].length; c++) { 
       var cardImg = document.createElement('img'); 
       cardImg.src = "http://www.airpim.com/png/public/card/" + arraycardbyuser[u][c] + "?width=292"; 
       cardImg.id = "immaginecard"; 
       userTdcard.appendChild(br); 
       userTdcard.appendChild(cardImg); 

      } 

      var userdivNome = document.createElement('div'); 
      userdivNome.id = "diverso"; 
      userTdinfo.appendChild(userdivNome); 

      var userdivVanity = document.createElement('div'); 
      userdivVanity.id = "diverso"; 
      userTdinfo.appendChild(userdivVanity); 

      var nome = "Nome: "; 
      var vanityurl = "Vanity Url: "; 
      userdivNome.innerHTML = nome + arrayEntita[u].__title__; 
      userdivVanity.innerHTML = vanityurl + arrayEntita[u].vanity_urls[0]; 

      userTr.appendChild(userTdcard); 
      userTr.appendChild(userTdinfo); 
      userTable.appendChild(userTr); 
     } 

     wrapper.appendChild(userTable); 
    } 

我不知道這是否檢查:

if (i + 1 == arrayEntita.length) 
    BuildTable(); 

,但沒有別的,你必須檢查是否全部responseses已執行buildtable之前)返回(;

+0

我在嘗試,但如果我從displayArrayCards中調用BuildArrayEntita(就像你做的那樣)它不起作用(這就是爲什麼我沒有使用不同的函數,而我把所有的代碼放在一個方法中)。 – user1453638

+0

什麼不工作?你是否試圖檢查你的objectivityjson.cards以確保它包含你期望它包含的內容。嘗試放入console.log(「 - unique text--」);在每個方法的開始(以及onreadystatechange函數中)。然後你可以看到執行的順序。 – Dappergoat

+0

我在這裏和那裏有一些提醒,以瞭解發生了什麼,但我看不到其中之一。 – user1453638

1

AJAX請求是異步的。它們在執行期間到達未知的時間段,並且JavaScript不會等待服務器在繼續之前進行回覆。有同步XHR,但不適合理想用途。如果你這樣做,你會失去AJAX的全部想法。

通常做的事情是傳入一個「回調」 - 一個稍後執行的函數,具體取決於您希望執行的時間。在你的情況,你想你收到數據後,產生的表:

function getData(callback){ 
    //AJAX setup 
    var richiestaEntity = new XMLHttpRequest(); 

    //listen for readystatechange 
    richiestaEntity.onreadystatechange = function() { 

     //listen for state 4 and ok status (200) 
     if (richiestaEntity.readyState === 4 && richiestaEntity.status === 200) { 

      //execute callback when data is received passing it 
      //what "this" is in the callback function, as well as 
      //the returned data 
      callback.call(this,richiestaEntity.responseText); 
     } 
    } 
    richiestaEntity.open("GET", "danielericerca.json"); //third parameter defaults to true 
    richiestaEntity.send(); 
} 

function displayArrayCards() { 

    //this function passed to getData will be executed 
    //when data arrives 
    getData(function(returnedData){ 

     //put here what you want to execute when getData receives the data 
     //"returnedData" variable inside this function is the JSON returned 

    }); 
} 
+0

第二個json上的代碼只有在完成第一個json的工作後才能使用。所以我也應該在第二個json上工作,然後做表格。 我應該把第二個請求的執行裏面的函數getData(回調)? – user1453638

+0

@ user1453638如果它依賴於第一組獲取的數據,則必須在第一個「getData」內執行另一個「getData」。另一方面,您可能需要重構數據。多個AJAX調用也不理想。如果可能,請在一次通話中完成。 – Joseph

0

只要你所做的Ajax調用,把所有的readystatechange函數裏面的代碼的其餘部分。這樣,它將按順序執行所有操作。

編輯: @Dappergoat比我更好地解釋它。