2016-10-18 3 views
0

이 문제는 거대하고 복잡한 응용 프로그램에서 심오했으나 간단한 사용 사례로 재현 할 수 있습니다. 기본 브라우저 스레드가 사용 중이면 웹 작업자가 보낸 XHR은 기본 브라우저 스레드가 무료가 될 때까지 차단됩니다 거의 마치 작업자가 0ms 타임 아웃을 거친 보통 기능 인 것처럼 이 주 스레드에서 돌아 오기를 기다리고 있습니다. 실제로 일어나는 것은 아닙니다 : 동시성이 일어나고 있습니다. 우리는 로그 항목 중 타이밍에서 알 수 있습니다.하지만 XMLHttpRequest의 실제 전송은 기본 자바 스크립트 스레드가 비어있을 때만 수행 할 수있는 것처럼 보입니다.XHR을 보낼 때 웹 작업자가 실제로 병행하지 않습니까?

처음에는이 동작이 Internet Explorer에 국한된 것으로 생각했지만 실제로는 사용 사례에서 IE가 훨씬 느리기 때문에 실제로는 그렇게 보입니다. 따라서 기본 브라우저 스레드는 더 오랫동안 바쁘게 머물러 있습니다. 이 비 동시성 동작은 실제로 시도한 모든 브라우저 (IE, 크롬, Firefox)에 있습니다. 브라우저는 정확히 똑같은 동작을하지 않습니다. 때때로 open() 호출을 차단하고 때로는 send()를 차단하고 때로는 send()가 적시에 완료되지만 Fiddler와 같은 HTTP 디버거를 사용한다고 주장하는 경우가 있습니다 주 브라우저 스레드가 장기 실행 작업을 마칠 때까지 데이터가 실제로 서버로 전송되지 않았 음을 보여줍니다.

누군가가 왜 그런지, 그리고 웹 작업자가 적절하게 동시 패션으로 XHR을 보낼 수있는 방법이 있는지 알 수 있기를 바랍니다. BTW, 나는 이미 전체적인 문제의 핵심은 주 자바 스크립트 스레드가 얼마나 바쁜지 알고 있으므로 수정하지 말아주십시오. 우리 입니다. 도 마찬가지입니다. 그러나 문제가되는 장기간의 작업은 매우 복잡한 JS 기반 UI를 고객의 응용 프로그램에서 리플 로우하는 것이므로 으로 제한되어 있습니다.

<html> 
<body> 
<div id="test"></div> 
<script> 
worker = new Worker('worker.js'); 
// Wait for 2 seconds to be as sure as we can be that it has downloaded and installed the worker code 

setTimeout(proceed, 2000); 

function proceed() { 

    worker.postMessage(""); 
    console.log("Message sent to worker: " + new Date().getTime()); 

    // Now tie up the JS thread 
    setTimeout(function() { 
     console.log("Started crazy pointless loop: " + new Date().getTime()); 
     for (var i = 0; i < 500000; i++) { 
      var j = i/17, 
       k = j * j, 
       l = k/123; 
      document.getElementById("test").innerHTML = "l = " + l; 
     } 

     console.log("Finished crazy pointless loop: " + new Date().getTime()); 
    }, 0); 
} 
</script> 
</body> 
</html> 

과 worker.js 파일 :

addEventListener('message', function(e) { 

    var xhr = new XMLHttpRequest(); 
    xhr.onreadystatechange = function() { 
     if (xhr.readyState < 4) return; 
     console.log("Response received: " + new Date().getTime()); 
    } 
    console.log("Ready to open XHR: " + new Date().getTime()); 
    xhr.open("GET", "dummy.html?nocache=" + new Date().getTime(), true); 
    console.log("XHR opened: " + new Date().getTime()); 
    xhr.send(); 
    console.log("XHR sent: " + new Date().getTime()); 

}, false); 
+0

나는 이것을 지원할 데이터가 없으므로 이것은 답변이 아닙니다. 그러나 모든 브라우저가 주 스레드를 사용하여 주어진 도메인에 대한 동시 연결 수를 제한한다고 강력하게 판단합니다. HTTP 1.1은 지정된 도메인에 2 개 이하를 지정합니다. 대부분의 브라우저가 한계 값 _을 낮추지는 않지만, 모든 브라우저는 주 스레드를 통해 시행되는 상한선을 가지고 있습니다. 자세한 내용은 http://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser를 참조하십시오. –

답변

1

당신은 당신이 이미있어 이후 노동자에서 동 기적으로 XHR를 보내 더 나을 것

이 생식 경우 문제를 보여줍니다 별도의 스레드에서 작동 중 :

addEventListener('message', function(e) { 
    var xhr = new XMLHttpRequest(); 
    console.log("Ready to open XHR: " + new Date().getTime()); 
    xhr.open("GET", "dummy.html?nocache=" + new Date().getTime(), false); // false makes it synchronous 
    console.log("XHR opened: " + new Date().getTime()); 
    xhr.send(); 
    console.log("Response received: " + new Date().getTime()); 
}, false);