JavaScript는 백그라운드에서 AJAX 응답을 어떻게 처리합니까?


139

JavaScript는 단일 스레드에서 실행되므로 AJAX 요청을 한 후에 실제로 백그라운드에서 어떤 일이 발생합니까? 이것에 대한 더 깊은 통찰력을 얻고 싶습니다. 누군가 약간의 빛을 비출 수 있습니까?


6
꽤 좋은 설명이 여기 있습니다 : stackoverflow.com/questions/2914161/ajax-multi-threaded
Jonathan M

3
JavaScript 코드는 단일 스레드 (웹 작업자 제외)이지만 JavaScript 엔진을 실행하는 브라우저는 아닙니다.
Juan Mendes

@JuanMendes Event Queue가 다른 스레드에서 실행되는 동안 JavaScript는 한 스레드에서 실행됩니까?
Shaun Luttin

1
@ShaunLuttin 아니오, 이벤트 큐는 JavaScript를 시작합니다
Juan Mendes

답변:


213

커버 아래에 javascript에는 이벤트 큐가 있습니다. 자바 스크립트 실행 스레드가 완료 될 때마다 처리 할 대기열에 다른 이벤트가 있는지 확인합니다. 있는 경우 대기열에서 가져 와서 해당 이벤트를 트리거합니다 (예 : 마우스 클릭).

ajax 호출에있는 기본 코드 네트워킹은 ajax 응답이 수행되는시기를 알고 이벤트가 javascript 이벤트 큐에 추가됩니다. 원시 코드가 ajax 호출이 수행되는시기를 아는 방법은 구현에 따라 다릅니다. 스레드로 구현되거나 이벤트 중심 자체 일 수도 있습니다 (실제로 중요하지는 않습니다). 구현의 요점은 아약스 응답이 완료되면 일부 원시 코드가 완료되었음을 알리고 이벤트를 JS 큐에 넣는다는 것입니다.

당시에 Javascript가 실행되고 있지 않으면 이벤트가 즉시 트리거되어 ajax 응답 핸들러가 실행됩니다. 그 시점에서 무언가가 실행 중이면 현재 자바 스크립트 실행 스레드가 완료 될 때 이벤트가 처리됩니다. 자바 스크립트 엔진에 의한 폴링이 필요하지 않습니다. Javascript가 실행을 마치면 JS 엔진은 이벤트 큐를 검사하여 실행해야 할 다른 것이 있는지 확인합니다. 그렇다면, 다음 이벤트를 큐에서 팝하고 실행합니다 (해당 이벤트에 등록 된 하나 이상의 콜백 함수 호출). 이벤트 큐에 아무것도 없으면, JS 외부 인터프리터는 일부 외부 에이전트가 이벤트 큐에 다른 것을 넣고 다시 깨울 때까지 여유 시간 (가비지 콜렉션 또는 유휴)을 갖습니다.

모든 외부 이벤트는 이벤트 큐를 통과하고 자바 스크립트가 실제로 다른 것을 실행하는 동안 이벤트가 트리거되지 않으므로 단일 스레드 상태로 유지됩니다.

자세한 내용은 다음과 같습니다.


고마워 나는 이것이 사실이라고 생각했지만 확실하게 알고 싶습니다. 많은 'ajax'요청을 보내는 for 루프가 있습니다. 내 처리기 (각 요청에 대해 임의 순서로 반환)에서 시간이 걸릴 수있는 코드를 실행합니다. 이것이 확실히 작동한다는 것을 아는 것이 좋습니다.
iPadDeveloper2011

4
@telandor-이벤트는 FIFO 순서로 실행됩니다 (일부 예외가있을 수 있지만 의도는 FIFO입니다). 일부 이벤트는 약간 다르게 처리됩니다. 예를 들어 mousemove 이벤트는 대기열에 쌓이지 않습니다 (아마 대기열이 쉽게 오버플로 될 수 있기 때문에). 마우스가 움직이고 mousemove 이벤트가 큐에 이미 있고 다른 새 이벤트가 큐에 없으면 새 이벤트가 추가되지 않고 최신 위치로 업데이트됩니다. 인터벌 타이머 이벤트가 대기열에서 쌓이지 않도록 특별히 처리 될 것입니다.
jfriend00

2
@telandor-추가 설명이 필요하십니까? FIFO입니다. 내 답변에 몇 가지 참조 기사를 추가했습니다. 내가 아는 유일한 FIFO 실행은 즉시 트리거되는 이벤트입니다. .focus()항목을 호출 하면 초점이있는 항목의 "흐림"이벤트와 같은 몇 가지 다른 이벤트가 트리거됩니다. 이 블러 이벤트는 동 기적으로 발생하며 이벤트 큐를 거치지 않으므로 이벤트 큐에있을 수있는 다른 일 직전에 발생합니다. 실제로, 나는 이것이 실제적인 관심사 인 것을 결코 찾지 못했다.
jfriend00

2
@telandor-브라우저 문서 당 여러 개의 대기열이 없습니다. 하나의 대기열이 있으며 모든 것이 직렬로 FIFO 입력 / 출력됩니다. 따라서 타임 아웃과 아약스 응답, 마우스 이벤트 및 키보드 이벤트는 모두 같은 큐에 들어갑니다. 먼저 대기열에 넣은 것이 먼저 실행됩니다.
jfriend00

1
@CleanCrispCode-Thx. 내 답변에 유용한 참고 자료로 추가했습니다.
jfriend00

16

여기서는 자바 스크립트에서 이벤트 처리에 대한 매우 완벽한 문서를 찾을 수 있습니다 .
그것은 Opera 브라우저에서 자바 스크립트 구현을 작업하는 사람에 의해 작성되었습니다.

보다 정확하게는 제목, "이벤트 흐름", "이벤트 큐"및 "비 사용자 이벤트"를 살펴보십시오.

  1. 자바 스크립트는 각 브라우저 탭 또는 창마다 단일 스레드로 실행됩니다.
  2. 이벤트는 순차적으로 대기하고 실행됩니다.
  3. XMLHttpRequest는 구현에 의해 실행되고 콜백은 이벤트 큐를 사용하여 실행됩니다.

참고 : 원래 링크는 link 였지만 이제는 종료되었습니다.


1

답변에 언급 된 아약스 구현에 대해 조금 자세히 설명하고 싶습니다.

(일반) 자바 스크립트 실행이 있지만 하지 위의 답변에서 잘 언급 한 바와 같이 - - 멀티 스레드 그러나 ,의 실제 처리 AJAX responses(뿐만 아니라 요청 처리) 일 하지 자바 스크립트, 그리고 - 보통 - 입니다 멀티 스레드. ( 위에서 논의 할 XMLHttpRequest의 크롬 소스 구현 참조 )

다음 코드를 살펴 보겠습니다.

var xhr = new XMLHttpRequest();

var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );

xhr.onload = function( e ) {
		console.log(t() + ': step 3');
    
    alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');

after an AJAX request is made(-1 단계 후) js 코드 실행이 진행되는 동안 (2 단계 이후) 브라우저는 다음과 같은 실제 작업을 시작합니다. 1. tcp 요청 형식 지정 2. 소켓 열기 3. 헤더 보내기 4. 핸드 쉐이킹 5. 보내기 본문 6. 대기 응답 7. 헤더 읽기 8. 본문 읽기 등이 모든 구현은 일반적으로 js 코드 실행과 병렬로 다른 스레드에서 실행됩니다. 예를 들어 언급 된 크롬 구현은 Threadable Loader go digg-into 😉를 사용합니다 (페이지로드의 네트워크 탭을 보면 인상을 얻을 수 있으며 동시 요청이 표시됩니다).

결론적으로, 적어도 대부분의 I / O 작업은 동시에 / 비동기 적으로 수행 될 수 있습니다 ( 예를 들어 await 를 사용하여이를 활용할 수 있음 ). 그러나 해당 작업 (발행, js 콜백 실행)과의 모든 상호 작용은 모두 동 기적입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.