분류 javascript

브라우저에서 Javascript가 작동하는 방식에 대해 쓴 글

컨텐츠 정보

  • 조회 302 (작성일 )

본문

자바 스크립트 내부 : 후드 아래는 무엇입니까? 


Javascript를 시작하고 실행하기 위해 많은 것을 알 필요가 없습니다. 실제로 언어의 내부 작업을 이해하지 않고도 본격적인 프로덕션 지원 앱을 구축 할 수 있습니다. 

이것은 축복이자 저주입니다. 이 언어에는 많은 채택자가 있지만 소수의 마스터만 있습니다.


이 실현으로 인해 Javascript가 실제로 어떻게 작동하는지 이해하려고 노력했습니다. 여행은 끝나지 않았지만 안개가 들기 시작했습니다. 그리고“Javascript 란 정확히 무엇입니까?”라는 질문으로 시작되었습니다.


Javascript 란 무엇입니까? 

공식적으로 말하면 Javascript는 단일 스레드, 비 차단 비동기 프로그래밍 언어입니다.


무엇을 기다립니다? 

표면 상으로 (적어도 나에게는)이 정의는 모순되고 혼란스럽고 더 많은 질문으로 이어졌습니다. 단일 스레드 프로그램은 어떻게 비차단일 수 있습니까? 어떻게 비동기식 일 수 있습니까?


이것들은 모두 매우 유용한 질문입니다. 그러나 나에게 견디십시오. 그들은 또한 대답을 가지고 있습니다. 답변은 런타임 환경인 Javascript의 핵심에 있습니다.


자바 스크립트 런타임 


Javascript 런타임 환경은 코드를 작동시키는 요소이며, Javascript가 공식적인 정의에 모든 복잡한 용어를 가질 수 있게 하며, 브라우저의 맥락에서 주로 4 가지의 조합입니다.

  1. 자바 스크립트 엔진
  2. 웹 API
  3. 콜백 대기열
  4. 이벤트 루프

각 부분을 개별적으로 살펴 보겠습니다.


Javascript 런타임 환경은 상황에 따라 다른 모양과 형태를 취할 수 있습니다. 

예를 들어, 브라우저의 런타임 환경 (세부적으로 살펴볼)은 node.js의 환경과 다릅니다. 

그러나 이러한 차이점은 대부분 구현에 있습니다. 

논의하는 개념은 컨텍스트와 상관없이 대부분의 Javascript 런타임 환경에 적용됩니다.


자바 스크립트 엔진 


Javascript 엔진은 런타임 환경의 핵심이며, 주요 목적은 사람이 읽을 수 있는 스크립트를 기계가 읽을 수 있는 코드로 변환하는 것입니다.


또한 코드 실행을 추적하기 위해 호출 스택 (LIFO 스택 데이터 구조를 생각)을 관리하며 실행 자체는 항상 단일 스레드에서 동기 방식으로 수행됩니다. 또한 엔진은 가비지 수집, 최적화 및 자체 기사가 필요한 다른 많은 것들을 수행합니다.


귀하의 시간 가치가 있는 모든 엔진에는 Javascript를 표준화 하기 위해 작성된 스크립팅 언어 사양 인 ECMAScript의 구현도 포함됩니다. 이것이 엔진이 while 루프가 무엇인지, Math.round (x)가 무엇을 해야 하는지 "알 수 있게"하는 것입니다. 필요한 것은 많은 while 루프, 몇 가지 함수 정의 및 일부 변수 (즉, 필요한 것이 ECMAScript 사양에 정의되어있는 경우)이면 Javascript 엔진은 자체적으로 코드를 처리 할 수 ​​있습니다.


그러나 Javascript는 단순한 함수 정의 그 이상입니다. 많은 작업을 수행 할 수 있는 강력한 언어로, 다음 퍼즐, 웹 API로 연결됩니다.


웹 API 


V8과 같은 Javascript 엔진의 소스 코드를 체크 아웃 하면 표준 Javascript 스펙의 일부라고 생각한 많은 기능이 단순히 존재하지 않음을 알 수 있습니다. 적절한 예는 setTimeout 함수입니다. 나는 당신에 대해 모른다. 그러나 나를 위해 setTimeout은 표준 자바 스크립트이다. 그러나 엔진 내에 없으면 어디에 있습니까?


웹 API를 입력하십시오. 웹 API는 자바 스크립트 언어를 확장하는 주요 브라우저 별 구현입니다. 예를 들어 Chrome 콘솔을 열고 다음과 같이 입력하면


function main(){
  setTimeout(()=>console.log('Hello World!'), 5000);
};

main();


"Hello World"가 예상대로 5 초 후에 콘솔에 인쇄됩니다. 이 코드는 Chrome의 웹 API에 자체 자바 스크립트 엔진 V8에 내장 된 setTimeout 구현이 있기 때문에 작동합니다. 마찬가지로 DOM도 Javascript 엔진의 일부가 아닙니다. DOM과 관련된 모든 것 : 이벤트 리스너, 접근 자 또는 조작자 등이 모두 정의되어 있습니다. 웹 API라고 생각했습니다!


이 시점에서 매우 논리적 인 질문은 Javascript 엔진이 이러한 기능을 모른다면 스크립트에서 "웹 API"함수 호출을 어떻게 처리 할 것인가입니다.


대답은 브라우저가 웹 API를 Javascript 엔진에 임베드하는 방법에 있습니다.


Javascript 엔진이 심볼을 확인하려고 하면 로컬 범위에서 시작하여 일련의 범위로 올라갑니다. 체인의 맨 끝에는 "글로벌"범위가 있습니다. Javascript 엔진 초기화의 일부로 모든 호스트 환경은 이 전역 범위에 자체 API를 추가하여 함수 및 해당 핸들러를 Javascript 엔진에 노출 시킬 수 있습니다.


이것을 더 잘 이해하려면 예제로 돌아가 봅시다.


function main(){
  setTimeout(()=>console.log('Hello World!'), 5000);
};

main(); 


이 코드를 Chrome 브라우저에 복사하면 실제로 어떻게 됩니까?

  • V8 엔진은 main()을 호출 스택에 추가하여 시작합니다.
  • 그런 다음 엔진은 범위 체인에서 setTimeout 함수 정의를 찾습니다. (setTimeout이 엔진에 내장되어 있지 않으므로 글로벌 범위에서 사용할 수 있습니다).
  • V8 엔진은 setTimeout()을 호출 스택으로 푸시하고 웹 API의 setTimeout 정의를 "호출"하면 Javascript의 메인 스레드 외부에서 브라우저가 동일한 기본 구현을 시작합니다.
  • 이 시점에서 엔진에 관한 한 작업이 완료됩니다. 따라서 setTimeout()이 콜 스택에서 튀어 나와 곧바로 main()이옵니다.

괜찮아. 하지만 그럴 수 없습니다. 5 초 지연 후에도 여전히 콜백이 실행됩니다. 콜백에 대해 말하면 실제로 어떻게 되었습니까?


이러한 답변을 찾으려면 다음 런타임 퍼즐 인 콜백 대기열을 살펴 봐야 합니다.


콜백 큐 


그러면 저주 받은 콜백은 어디로 갔습니까? 

그에 도달하기 전에 먼저 콜백 함수의 역할을 이해해야 합니다.


콜백 함수는 본질적으로 자바 스크립트 엔진과 비동기 웹 API 작업 간의 바인딩이며, 일반적으로 비동기 작업이 작업을 완료 한 후 수행 할 작업에 대한 지침이 있습니다. 엔진의 메인 스레드 외부에서 실행되는 모든 코드는 엔진과 다시 통신하기 위해 항상 관련 콜백이 필요합니다.


아직 알지 못했다면 이것이 비동기 자바 스크립트의 기본 개념입니다.


자바 스크립트 엔진의 메인 스레드 외부에서 실행되는 것은 비동기 작업입니다.


좋아요. 모두 훌륭하지만 콜백은 어디에 있습니까?


조금 되감습니다.


V8 엔진이 setTimeout 웹 API 바인딩을 "호출"한 후 일부 브라우저 고유의 원시 코드는 5 초 지연 타이밍으로 태스크됩니다. 이것은 엔진의 메인 스레드 외부에서 발생하는 비동기 작업이며 구현 세부 정보는 중요하지 않습니다. 이와 동일한 기본 코드는 "손실 된"콜백 함수가 집으로 돌아 오는 길을 찾도록 보장 할 책임이 있습니다.


어떻게 이럴까요?


Javascriptland에는 실행을 기다리는 콜백을 위한 특별한 장소가 있습니다. 콜백 대기열이며 Javascript 런타임에서 비동기 Javascript를 가능하게 하는 두 가지 중요한 요소 중 하나입니다.


네이티브 코드는 그 존재를 알고 있으며 비동기 작업이 완료되면 콜백 함수를 콜백 큐로 푸시합니다.


콜백 함수는 거의 집에 있지만 아직 거기에 없습니다. Javascript 런타임 퍼즐에는 여전히 마지막 조각이 남아 있습니다.


이벤트 루프 


이벤트 루프는 무엇입니까? 

이벤트 루프는 Javascript 엔진과 콜백 큐 사이의 젤이며 두 가지 작업을 수행합니다.


먼저 자바 스크립트 엔진의 호출 스택이 비어 있는지 정기적으로 확인합니다. 그렇다면 콜백 대기열에서 콜백을 가져와 콜 스택에 배치하여 효과적으로 실행되도록 예약합니다.


정말 간단합니다.


콜백 큐와 이벤트 루프는 비동기 자바 스크립트 코드를 작동 시킵니다. 전자는 완료된 비동기 작업의 콜백 함수를 대기 시키고 후자는 자바 스크립트의 메인 스레드에서 실행되도록 예약합니다.


Full Circle 


”… 단일 스레드의 비 차단 비동기 프로그래밍 언어.”


나는 이것이 자바 스크립트의 후드에서 실제로 일어나는 일에 대해 상당히 유익한 정보를 얻었기를 바랍니다. 위의 정의는 몇 분 전에 그 일이 어떻게 되었는지 더 이해가 됩니다.


나는 일을 매우 일반화하려고 노력했다. 이러한 개념이 브라우저의 런타임뿐만 아니라 발생할 수 있는 Javascript 런타임 환경에도 적용 가능하다는 것을 이해하기 위해서 입니다.


나는 이것이 당신이 이전에는 없었던 많은 새로운 질문을 열어 줄 것이라고 확신합니다. 그러나 그것은 요점입니다. 질문은 연구로 이어지고 더 혼란스러워 질 수 있지만, 계속한다면 결국에는 대답으로 이어질 것입니다. 그리고 그것이 당신이 배우는 방법입니다.


따라서 많은 텍스트를 몇 가지 글 머리 기호로 요약하면 다음과 같습니다.


  • Javascript 런타임은 Javascript 코드를 작동시키는 것입니다. 다양한 모양과 형태 (브라우저, node.js)를 사용할 수 있습니다. 그러나 런타임의 기본 개념은 모든 환경에서 동일하게 유지됩니다. 브라우저의 런타임 환경은 Javascript 엔진, 많은 웹 API, 콜백 큐 및 이벤트 루프로 구성됩니다.
  • Javascript 엔진은 사람이 읽을 수 있는 Javascript 코드를 기계가 읽을 수 있는 바이트 코드로 변환하여 항상 단일 스레드에서 실행합니다. 또한 콜 스택을 관리하고 다른 많은 작업을 수행합니다.
  • 웹 API는 Javascript 엔진의 글로벌 오브젝트에 추가되는 자체 기능으로 Javascript 언어를 확장합니다. 이러한 기능 중 일부는 동기식이며 일부는 비동기식 일 수 있습니다.
  • 콜백 대기열은 Javascript 엔진에 의해 실행되기를 기다리는 콜백을 대기열에 넣습니다. 콜백은 일반적으로 항상 일부 비동기 작업과 연결됩니다.
  • 이벤트 루프는 Javascript 엔진과 콜백 큐 사이의 겔입니다. 그 역할은 콜백을 콜백 대기열에서 엔진의 콜 스택으로 옮겨 실행하는 것입니다.
  • 콜백 대기열과 이벤트 루프는 자바 스크립트의 비동기 (및 비 차단) 특성의 핵심입니다.


자원 


  1. 독서보다는 시청을 좋아한다면 이벤트 루프가 무엇인지 확인하는 것이 좋습니다. 필립 로버츠. 진심으로 확인하십시오.
  2. 이 스택 오버플로 포스트는 V8 엔진과 웹 API 사이의 링크를 설명하고 콜백 큐에 대해 설명합니다.