이벤트 루프 이해
저는 그것에 대해 생각하고 있고 이것이 제가 생각해낸 것입니다.
아래에서 이 코드를 살펴보겠습니다.
console.clear();
console.log("a");
setTimeout(function(){console.log("b");},1000);
console.log("c");
setTimeout(function(){console.log("d");},0);
요청이 들어오고, JS 엔진은 위의 코드를 단계별로 실행하기 시작합니다.처음 두 통화는 동기화 통화입니다.하지만 그것에 관해서라면.setTimeout
메서드, 비동기 실행이 됩니다.그러나 JS는 즉시 그것으로부터 돌아와 계속 실행하고, 이것은 다음과 같습니다.Non-Blocking
또는Async
그리고 그것은 다른 것들에 대해 계속 작업을 합니다.
이 실행 결과는 다음과 같습니다.
cd b
으로 두 그서기으로두번째는적.setTimeout
먼저 완료되었으며 콜백 기능이 첫 번째 기능보다 더 일찍 실행되므로 이는 됩니다.
은 첫 두 요청으로 JS Engine은 이 작업을 계속 실행하고 첫 번째 요청을 완료하지 않으면 두 번째 요청으로 이동하지 않습니다.은 하만좋점다음과같은차단작기것않다입니는는다다와 같은 차단 을 기다리지 않는다는입니다.setTimeout
새 수신 요청을 수락하기 때문에 더 빨리 해결할 수 있습니다.
하지만 다음 항목에 대해 질문이 있습니다.
#1: 단일 스레드 애플리케이션에 대해 이야기하고 있다면 어떤 메커니즘이 처리되는지 알 수 있습니다.setTimeouts
JS 엔진이 더 많은 요청을 수락하고 실행하는 동안?단일 스레드는 어떻게 다른 요청에서 계속 작동합니까?에서 setTimeout
다른 요청이 계속 들어오고 실행되는 동안.
#2: 만약 이것들이setTimeout
더 많은 요청이 들어오고 실행되는 동안 기능이 백그라운드에서 실행되는데, 백그라운드에서 비동기 실행을 수행하는 것은 무엇입니까?우리가 이야기하는 것은 무엇입니까?EventLoop
?
#3: 하지만 전체적인 방법은 그 안에 넣어야 하지 않을까요?EventLoop
모든 것이 실행되고 콜백 방법이 호출되도록?콜백 기능에 대해 이야기할 때 이해하는 것은 다음과 같습니다.
function downloadFile(filePath, callback)
{
blah.downloadFile(filePath);
callback();
}
이 인지 알 수 을 JS와 같은 함수에 수 .EventLoop
아마도 그것과 비슷한 것.async
C#의 키워드 또는 JS Engine이 취할 방법을 나타내는 일종의 속성은 비동기식이므로 그에 따라 처리되어야 합니다.
#4: 하지만 어떤 기사는 일이 어떻게 진행되는지에 대해 제가 추측하고 있던 것과는 완전히 반대로 말합니다.
이벤트 루프는 콜백 함수의 대기열입니다.비동기 함수가 실행되면 콜백 함수가 대기열로 푸시됩니다.자바스크립트 엔진은 비동기 함수가 실행된 후 코드가 실행될 때까지 이벤트 루프 처리를 시작하지 않습니다.
#5: 여기에 도움이 될 수 있는 이미지가 있습니다. 하지만 이미지의 첫 번째 설명은 4번 질문에서 언급한 것과 정확히 같은 것입니다.
그래서 제가 여기서 질문하는 것은 위에 나열된 항목들에 대한 설명을 구하는 것입니까?
1: 단일 스레드 애플리케이션을 말하는 경우 JS 엔진이 더 많은 요청을 수락하고 실행하는 동안 setTimeout을 실행하는 프로세스는 무엇입니까?그 스레드 하나가 다른 요청에도 계속 작동하지 않나요?그러면 다른 요청이 계속 와서 실행되는 동안 setTimeout 작업을 계속할 사람은 누구입니까?
노드 프로세스에서 프로그램의 JavaScript를 실제로 실행할 스레드는 하나뿐입니다.그러나 노드 자체 내에는 실제로 이벤트 루프 메커니즘의 작동을 처리하는 여러 스레드가 있으며, 여기에는 IO 스레드 풀과 몇 가지 다른 스레드가 포함됩니다.중요한 것은 이러한 스레드의 수가 스레드별 동시성 모델에서와 같이 처리되는 동시 연결 수와 일치하지 않는다는 것입니다.
" 실행"에 "setTimeout"을 하면 "setTimeout"이 됩니다.setTimeout
노드가 하는 모든 것은 기본적으로 미래에 한 번에 실행될 함수의 데이터 구조를 업데이트하는 것입니다.기본적으로 수행해야 하는 여러 가지 작업과 이벤트 루프의 모든 "체크"를 통해 하나를 선택하고, 대기열에서 제거한 후 실행합니다.
중요한 것은 노드가 대부분의 무거운 작업을 OS에 의존한다는 것입니다.따라서 수신 네트워크 요청은 OS 자체에서 실제로 추적되며 노드가 처리할 준비가 되면 시스템 호출을 사용하여 OS에 네트워크 요청을 요청하고 처리할 준비가 된 데이터를 요청합니다.IO "작업" 노드의 대부분은 "Hey OS, 데이터를 읽을 준비가 된 네트워크 연결이 되었습니까?" 또는 "Hey OS, 내 미결 파일 시스템 호출 중 데이터가 준비되었습니까?"설계를 "체크부터 다시합니다.내부 알고리즘과 이벤트 루프 엔진 설계를 기반으로 노드는 실행할 JavaScript의 "체크"를 하나 선택하고 실행한 다음 프로세스를 처음부터 다시 반복합니다.그것이 이벤트 루프가 의미하는 것입니다.노드는 기본적으로 항상 "다음으로 실행해야 할 자바스크립트가 무엇인가?"를 결정하고 실행합니다.한 이 과 OS 은 다음과 .setTimeout
또는process.nextTick
.
2: 더 많은 요청이 들어오고 들어오고 실행되는 동안 이러한 setTimeout이 백그라운드에서 실행된다면, 백그라운드에서 비동기 실행을 수행하는 것은 EventLoop에 대해 이야기하는 것입니까?
백그라운드에서 실행되는 JavaScript가 없습니다.프로그램의 모든 JavaScript는 한 번에 하나씩 전면과 중앙에서 실행됩니다.OS가 IO를 처리하고 노드가 준비되기를 기다리고 노드가 실행 대기 중인 Javascript 대기열을 관리합니다.
3: JS 엔진이 이벤트 루프에 넣을 수 있도록 비동기 기능인지 여부를 어떻게 알 수 있습니까?
노드 코어에는 시스템 호출을 하기 때문에 비동기식으로 고정된 함수 집합이 있으며, OS 또는 C++을 호출해야 하기 때문에 노드는 이 함수가 무엇인지 알고 있습니다.기본적으로 모든 네트워크 및 파일 시스템 IO와 하위 프로세스 상호 작용은 비동기적이며 JavaScript가 노드를 비동기적으로 실행할 수 있는 유일한 방법은 노드 코어 라이브러리에서 제공하는 비동기 함수 중 하나를 호출하는 것입니다.자체 API를 정의하는 npm 패키지를 사용하더라도 이벤트 루프를 생성하기 위해 npm 패키지의 코드가 노드 코어의 비동기 함수 중 하나를 호출하고 노드가 틱이 완료되었음을 알고 이벤트 루프 알고리즘을 다시 시작할 수 있습니다.
4 이벤트 루프는 콜백 기능의 큐입니다.비동기 함수가 실행되면 콜백 함수가 대기열로 푸시됩니다.자바스크립트 엔진은 비동기 함수가 실행된 후 코드가 실행될 때까지 이벤트 루프 처리를 시작하지 않습니다.
네, 이것은 사실이지만 오해의 소지가 있습니다.중요한 것은 일반적인 패턴입니다.
//Let's say this code is running in tick 1
fs.readFile("/home/barney/colors.txt", function (error, data) {
//The code inside this callback function will absolutely NOT run in tick 1
//It will run in some tick >= 2
});
//This code will absolutely also run in tick 1
//HOWEVER, typically there's not much else to do here,
//so at some point soon after queueing up some async IO, this tick
//will have nothing useful to do so it will just end because the IO result
//is necessary before anything useful can be done
네, 메모리에 있는 모든 피보나치 숫자를 동기화해서 하나의 눈금으로 세는 것만으로도 이벤트 루프를 완전히 차단할 수 있습니다. 그러면 프로그램이 완전히 정지됩니다.협력적 동시성입니다.JavaScript의 모든 눈금은 일정 시간 내에 이벤트 루프를 생성해야 합니다. 그렇지 않으면 전체 아키텍처가 실패합니다.
호스트 프로세스가 단일 스레드라고 생각하지 마십시오. 그렇지 않습니다.단일 스레드는 Javascript 코드를 실행하는 호스트 프로세스의 일부입니다.
배경 작업자들을 제외하고, 하지만 이것들은 시나리오를 복잡하게 만듭니다.
따라서 모든 js 코드는 동일한 스레드에서 실행되며, 두 개의 다른 js 코드 부분을 동시에 실행할 가능성은 없습니다(따라서 동시성 악몽을 관리할 수 없습니다).
실행 중인 js 코드는 호스트 프로세스가 이벤트 루프에서 가져온 마지막 코드입니다.코드에서는 기본적으로 동기식 명령 실행과 일부 이벤트가 발생할 때 나중에 실행할 기능 예약이라는 두 가지 작업을 수행할 수 있습니다.
다음은 예제 코드에 대한 나의 정신적 표현입니다(주의: 브라우저 구현 세부 정보를 잘 모릅니다!).
console.clear(); //exec sync
console.log("a"); //exec sync
setTimeout( //schedule inAWhile to be executed at now +1 s
function inAWhile(){
console.log("b");
},1000);
console.log("c"); //exec sync
setTimeout(
function justNow(){ //schedule justNow to be executed just now
console.log("d");
},0);
코드가 실행되는 동안 호스트 프로세스의 다른 스레드는 발생하는 모든 시스템 이벤트(UI 클릭, 파일 읽기, 네트워크 패킷 수신 등)를 추적합니다.
코드가 완료되면 이벤트 루프에서 제거되고 호스트 프로세스는 실행할 코드가 더 있는지 확인하기 위해 이벤트 루프로 돌아갑니다.이벤트 루프에는 두 개의 이벤트 핸들러가 더 포함되어 있습니다. 하나는 지금 실행(justNow 함수)하고 다른 하나는 1초 이내에 실행(in)합니다.잠시 동안 기능).
이제 호스트 프로세스가 발생한 모든 이벤트를 일치시켜 처리기가 등록되었는지 확인합니다.방금 나우가 기다리고 있는 이벤트가 발생한 것을 발견하고 코드를 실행하기 시작합니다.justNow 함수가 종료되면 이벤트 루프를 다시 확인하여 이벤트에 대한 핸들러를 검색합니다.1초가 지났다고 가정하면 다음과 같이 실행됩니다.잠시 동안의 기능 등...
이벤트 루프에는 콜 스택, 콜백 대기열 및 마이크로 태스크 대기열을 모니터링하는 간단한 작업이 있습니다.콜 스택이 비어 있으면 이벤트 루프가 마이크로 태스크 대기열에서 첫 번째 이벤트를 가져온 다음 콜백 대기열에서 이 이벤트를 콜 스택으로 푸시하여 효과적으로 실행합니다.이러한 반복을 이벤트 루프의 눈금이라고 합니다.
대부분의 개발자가 알고 있듯이 Javascript가 단일 스레드라는 것은 Javascript의 두 문장을 병렬로 실행할 수 없다는 것을 의미합니다.실행은 한 줄씩 발생하며, 이는 각 Javascript 문이 동기화되고 차단됨을 의미합니다.그러나 브라우저에서 제공하는 웹 API인 setTimeout() 함수를 사용하면 코드가 지정된 시간(밀리초) 후에 실행되도록 코드를 비동기식으로 실행할 수 있습니다.
예:
console.log("Start");
setTimeout(function cbT(){
console.log("Set time out");
},5000);
fetch("http://developerstips.com/").then(function cbF(){
console.log("Call back from developerstips");
});
// Millions of line code
// for example it will take 10000 millisecond to execute
console.log("End");
setTimeout은 콜백 함수를 첫 번째 매개 변수로 사용하고 시간(밀리초)을 두 번째 매개 변수로 사용합니다.브라우저 콘솔에서 위의 문을 실행하면 인쇄됩니다.
Start
End
Call back from developerstips
Set time out
참고: 비동기 코드는 모든 동기 코드 실행이 완료된 후 실행됩니다.
한 줄씩 코드를 실행하는 방법 이해
JS 엔진이 첫 번째 라인을 실행하고 콘솔에서 "시작"을 인쇄합니다.
두 번째 줄에는 cbT라는 setTimeout 함수가 표시되며, JS 엔진은 cbT 함수를 callBack 큐로 푸시합니다.
그 후 포인터가 7번 라인으로 바로 점프하고 거기서 약속과 JS 엔진이 cbF 기능을 마이크로태스크 대기열로 밀어넣는 것을 볼 것입니다.
그런 다음 수백만 개의 라인 코드를 실행하고 "종료"를 인쇄합니다.
메인 스레드 실행 종료 후 이벤트 루프는 먼저 마이크로 태스크 대기열을 확인한 다음 대기열을 호출합니다.우리의 경우, 그것은 마이크로 작업 대기열에서 cbF 기능을 가져와 콜 스택으로 밀어넣은 다음 콜백 대기열에서 cbT 기능을 선택하여 콜 스택으로 밀어넣습니다.
JavaScript는 고급 단일 스레드 언어, 해석 언어입니다.이것은 JS 코드를 기계 코드로 변환하는 인터프리터가 필요하다는 것을 의미합니다.인터프리터는 엔진을 의미합니다.크롬용 V8 엔진과 사파리용 웹킷.모든 엔진에는 메모리, 콜 스택, 이벤트 루프, 타이머, 웹 API, 이벤트 등이 포함되어 있습니다.
이벤트 루프: 마이크로 태스크 및 매크로 태스크
이벤트 루프의 개념은 매우 간단합니다.JavaScript 엔진이 작업을 대기하고 실행한 다음 절전 모드로 전환하여 더 많은 작업을 기다리는 무한 루프가 있습니다.
작업이 설정되고 엔진이 작업을 처리하며 더 많은 작업을 기다립니다(휴면 상태에서 CPU를 거의 사용하지 않음).엔진이 작동 중일 때 작업이 발생한 후 대기열에 들어갈 수 있습니다.태스크는 대기열을 형성합니다. 소위 "매크로 태스크 대기열"
미세 작업은 전적으로 우리의 코드에서 나옵니다.이들은 일반적으로 약속에 의해 만들어집니다. .then/catch/finally 핸들러의 실행은 마이크로태스크가 됩니다.마이크로태스크는 다른 형태의 약속 처리이기 때문에 대기의 "표지 아래"에서도 사용됩니다.매 매크로 작업 직후 엔진은 다른 매크로 작업, 렌더링 또는 기타 작업을 실행하기 전에 마이크로 작업 대기열에서 모든 작업을 실행합니다.
언급URL : https://stackoverflow.com/questions/21607692/understanding-the-event-loop
'programing' 카테고리의 다른 글
C에서 문자열 반전 (0) | 2023.07.25 |
---|---|
Angular 빌드 및 실행 방법 (0) | 2023.07.25 |
C에서 가장 높은 순서 비트 찾기 (0) | 2023.07.20 |
Firebase에서 확인 이메일을 보내는 방법은 무엇입니까? (0) | 2023.07.20 |
데이터베이스에 암호를 저장하는 기본 방법 (0) | 2023.07.20 |