2012-06-28 40 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比我更好地解释它。