2014-11-14 9 views
0

잠시 동안 시스템을 사용하지 않는 코드 블록 전에 사용자 인터페이스를 업데이트하는 코드 줄을 실행하면 UI가 업데이트되지 않습니다. 코드 아래를 참조하십시오 :자바 스크립트. 코드가 실행되지 않았습니다. UI가 업데이트되지 않았습니다.

<html> 
 
    <body> 
 
    <div id="acc"> 
 
     <input type="text" value="start" id="id1"/> 
 
     <input type="text" value="e0" id="id2"/> 
 
    </div> 
 
    <script> 
 
     myFunction(); 
 
     function myFunction() { 
 
     document.getElementById("id1").value="1"; 
 
     var j=true; 
 
     for(var i=0;j==true;i++){ 
 
      document.getElementById("id2").value="e"+i; 
 
      if(i==999999) 
 
      j=false; 
 
     } 
 
     document.getElementById("id1").value="2"; 
 
     } 
 
    </script> 
 
    </body> 
 
</html>

값 1은 입력 텍스트 (ID1)에 할당되지 않습니다. JavaScript 코드가 동 기적으로 실행되지 않는 것과 같습니다.

누군가가이 문제를 해결할 수 있습니까?

+0

'1'이 id1''에 할당되지 않은 사용하려고 할 수 있습니다 'for' 루프 바로 다음에 – blgt

+0

예.하지만 루프가 10 초 걸립니다. 루핑하는 동안 나는 1을보아야한다. – Marc

+0

@Marc, 당신이 오해 javascript가 실행을 마칠 때까지 화면이 업데이트되지 않습니다 .... – Soren

답변

1

;

<html> 
 
    <body> 
 
    <div id="acc"> 
 
     <input type="text" value="start" id="id1"/> 
 
     <input type="text" value="e0" id="id2"/> 
 
    </div> 
 
    <script> 
 
     myFunction(); 
 
     function myFunction() { 
 
     document.getElementById("id1").value="1"; 
 
     setTimeout(function(){ 
 
      for(var i=0;i<=999999;i++){ 
 
       document.getElementById("id2").value="e"+i; 
 
      } 
 
      document.getElementById("id1").value="2"; 
 
      },5); 
 
     } 
 
    </script> 
 
    </body> 
 
</html>

+0

모든 이벤트가 완료되면 화면이 업데이트됩니다 (자바 스크립트는 이벤트 루프에서 실행 됨). 따라서 setTimeout 함수가 실행되면 화면이 얼마나 오랜 시간이 걸렸는 지 상관없이 끝나면 업데이트됩니다. 언제든지 하나의 이벤트 만 실행되므로 더 많은 이벤트가 있으면 이전 이벤트가 완료 될 때까지 큐에 대기하게됩니다. – Soren

1

값이 업데이트됩니다. 화면은 JavaScript 실행이 완료 될 때까지 (JavaScript 실행으로 UI 잠금) 업데이트되지 않습니다. 추가 된 console.log는 예상 한 내용을 인쇄합니다.

myFunction(); 

function myFunction() { 
    console.log(document.getElementById("id1").value); // outputs "start" as expected 
    document.getElementById("id1").value = "1"; 
    console.log(document.getElementById("id1").value); // outputs "1" as expected 
    var j = true; 
    for (var i = 0; j == true; i++) { 
     document.getElementById("id2").value = "e" + i; 
     if (i == 999999) j = false; 
    } 
    document.getElementById("id1").value = "2"; 
} 

하나의 해결 방법은 루프를 "청크"로 분할하는 것입니다. 한 번에 1000 번 반복을 실행 한 다음을 사용하여 다음 1000 번의 반복을 1ms 후에 실행하도록 예약합니다. 우리는 전체 세트 이상 반복 될 때까지 우리는 반복 :

myFunction(); 

function myFunction() { 
    // iterator which we count up each loop 
    var i = 0; 

    // set to initial value 
    document.getElementById("id1").value = "1"; 

    function processDone() { 
     document.getElementById("id1").value = "2"; 
    } 

    function processChunk() { 
     var maxLoopsPerCall = 1000; 
     while (maxLoopsPerCall-- > 0) { 
      document.getElementById("id2").value = "e" + i; 

      // if we're done, we call our done function and call return (so we don't schedule any more chunks 
      if (i == 999999) { 
       processDone(); 
       return; 
      } 

      i += 1; 
     } 

     // schedule to process next chunk of the loop 
     setTimeout(processChunk, 1); 
    } 

    // schedule to process the first chunk of the loop 
    setTimeout(processChunk, 1); 
} 
당신은 다음과 같이 코드 비동기을해야

http://jsfiddle.net/8kddxqmd/

+0

고맙습니다 #Strille,이게 버그가 아니십니까? 이 문제를 어떻게 해결할 수 있습니까? – Marc

+0

다른 대답이 지적한대로 setInterval 또는 setTimeout을 사용하여 루프를 작은 조각으로 분할해야합니다. 그렇게하면 각 JavScript 실행이 중요한 시간을 차지하지 않으므로 UI가 업데이트 될 수 있습니다. 또는 최소한 UI 앞에 값이 "1"인 입력을 업데이트 할 수 있도록 루프 앞에 지연이 있어야합니다. – Strille

+0

@Marc : 루프를 "덩어리"로 나누는 방법을 예제로 추가했습니다. – Strille

1

당신은 당신이 그것에 2``할당하고 있기 때문에 window.setInterval()

var id1 = document.getElementById("id1"); 
 
var id2 = document.getElementById("id2"); 
 
id1.value = 1; 
 
var i = 0; 
 
var t = setInterval(function() { 
 
    if (999999 < i) { 
 
    clearInterval(t); 
 
    id1.value = 2; 
 
    } 
 
    id2.value = 'e' + i; 
 
    i++; 
 
}, 6);
<input type="text" value="start" id="id1" /> 
 
<input type="text" value="e0" id="id2" />

관련 문제