2012-02-19 5 views
0

정보를 가져 와서 while/for 루프가 혼합 된 데이터베이스로 업데이트하는 javascript/jquery 코드가 있습니다. 가져 오는 동안 진행중인 작업 진행 로그를 보여주는 div가 있습니다. 파이어 폭스에서는 스크립트가 실행되는 동안 div가 동시에 업데이트됩니다. Chrome에서는 전체 루프를 실행하여 로그를 보관하고 스크립트 실행이 끝날 때까지 로그 만 출력합니다. 왜 이런 일이 일어나는 지 아는 사람이 있습니까?Google 크롬에서 Javascript 출력이 다시 표시되는 이유는 무엇입니까?

$(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

+0

function add_text (text) { $ ("# status_text"). append ("
"+ text); } – user1218595

+1

코드가 동기식 인 경우 (일반적으로 브라우저는 현재 동기 코드가 완료 될 때까지 다시 그리지 않습니다.) 그것이 동기화되면, 파이어 폭스가 끝나기 전에 다시 그려진다는 것에 놀랐다. –

답변

4

당신은 (일반적으로 매우 바람직하지 않은) 동기 아약스 호출을 사용하는 . 브라우저는 Ajax 호출이 완료 될 때까지 모든 활동을 차단할 수 있습니다. 동기식 아약스 호출 중에 브라우저가 화면을 업데이트하는지 여부는 브라우저에 달려 있습니다.

asychronous ajax 만 사용하도록 코드를 다시 작성하면 코드가 훨씬 향상됩니다. 비동기식 아약스 호출을 사용하기 위해 코드를 올바르게 구조화하는 데는 약간의 작업이 필요하지만 비동기식 아약스 호출 중에도 브라우저는 완전히 반응합니다.

원래 구현에서 변수를 어떻게 사용했는지는 모르겠지만 (포함 된 코드에서 선언되거나 초기화되지 않았으므로) 사용할 수있는 일반적인 구조입니다. 전통적인 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

+0

한 번에 하나의 카드 만 업데이트하면됩니다. 비동기 아약스를 수행하면 즉시 모든 작업을 수행합니다. 한 번에 하나씩해야합니다. 다음 카드로 이동하기 전에 Ajax 함수가 완료 될 때까지 (for my fetch_card function) for 또는 while 루프를 대기시킬 수있는 방법이 있습니까? – user1218595

+0

@ user1218595 - 내가 말했듯이 코드를 재구성해야합니다. 하나의 아약스 호출을 실행 한 다음 그 하나의 성공 처리기에서 다음 아약스 호출 등을 시작하십시오. 지금과 같이 간단한 'for' 루프로 그렇게 할 수 없습니다. – jfriend00

관련 문제