1. 자바스크립트는 single-thread 언어다.
JavaScript는 단일 스레드이다. 한 번에 하나의 작업만 실행할 수 있다.
일반적으로 큰 문제는 아니지만 만약 30 초가 걸리는 어떤 작업을 실행한다고 상상해보자.
해당 작업 중에 어떠한 다른 작업도 할 수 없다. 현대 웹 애플리케이션에서 이러한 웹 사이트를 원하는 사람은 아마 없을 것이다.
다행히 브라우저는 JavaScript 엔진 자체가 제공하지 않는 웹 API 기능을 제공한다.
여기에는 DOM API, setTimeout, HTTP 요청 등이 있다. 이를 통해 비동기 동작을 수행할 수 있다.
간단하게 setTimeout 함수로 어떻게 비동기 처리가 가능한지 알아보자!
우리가 함수를 호출하면 그 함수는 Call Stack 이라는 항목에 추가된다.
이 호출 스택은 JS 엔진의 일부이며 브라우저에 한정되지 않는다. 그리고 함수가 값을 리턴하면 스택에서 제거된다.
respond 함수의 호출은 setTimeout 함수를 반환한다. setTimeout은 웹 API에 의해 제공된다.
이를 통해 메인 스레드를 차단하지 않고 작업을 지연시킬 수 있다.
setTimeout 함수에 전달한 콜백 함수인 화살표 함수 () => {return 'Hey'}가 Web API에 추가된다.
그 동안 setTimeout 함수와 respond 함수가 스택에서 튀어나와 모두 값을 반환할 것이다!
Web API에서 타이머는 우리가 전달한 두 번째 인수인 1000ms 동안 실행된다.
또한 콜백 함수는 즉시 콜 스택에 추가되지 않고 대신 큐에 전달된다.
이제 이벤트 루프가 자신의 유일한 작업을 수행 할 시간이다. 큐와 호출 스택을 연결하는 것이다!
만약 호출 스택이 비어있는 경우 큐의 첫 번째 항목이 호출 스택에 추가된다.
마찬가지로 콜백 함수가 콜 스택에 추가되고, 호출되고, 값을 반환하고, 스택에서 제거된다.
2. 자바스크립트 이벤트 루프 동작 원리 요약
www.youtube.com/watch?v=8aGhZQkoFbQ&feature=emb_title
위 영상을 보고 요약한 내용을 적어보았다.
싱글 스레드 런타임이란 하나의 싱글 콜 스택만을 가지고 있음을 의미한다.
콜 스택은 말그대로 함수를 담는데 쓰이는 스택 자료구조이다.
함수가 호출이 되면 함수는 차례대로 콜 스택에 쌓이고 해당 함수가 리턴이 되면 콜 스택에서 사라진다.
blocking에 대한 정확한 정의는 존재하지 않는다. blocking이란 그저 느리게 동작하는 코드일 뿐이다.
통신의 과정을 거치는 네트워크 요청이나 이미지 프로세싱은 느리다.
이러한 느린 동작이 콜 스택에 남아있는 것을 보고 보통 blocking이라 한다.
그러면 이러한 것이 왜 문제일까?
문제는 바로 브라우저에서 이러한 작동 방식으로 자바스크립트가 돌아간다는 점이다.
그리고 그것은 사용자에게 UX의 관점에서 매우 안 좋은 경험을 줄 수 있다는 것이다.
어떤 특정 동작이 30초가 걸리는 작업이 있는데 그 작업을 수행하는 동안 다른 아무것도 할 수 없는 상황을,,
아무도 그런 웹사이트는 사용하지 않을 것이다.
이러한 해결책으로 콜백 함수가 나왔다.
근데 도대체 콜백함수는 어떤 원리로 호출되는 것일까?
여기서 이벤트 루프의 역할과 동시성이라는 키워드가 중요하다!
모든 web api는 작동이 완료되면 콜백 함수를 테스크 큐에 밀어넣는다.
여기서 이벤트 루프가 중요한 역할을 하는데 이벤트 루프는 콜 스택과 테스크 큐를 지켜보다가 콜 스택이 비어있으면 테스크 큐의 첫번째 콜백을 스택에 쌓도록하는 역할을 담당한다.
즉 프론트 단에서 비동기 함수가 호출되는 방식은 곧 이벤트 루프의 동작 방식과 같다.
동기적인 콜백은 바로 콜스택에서 작동하지만 dom api나 fetch 같은 web api 같은 경우 무조건 테스크 큐를 통해 스택이 비어있는 경우에 스택으로 들어와 실행이 되는 것이다.
그리고 그런 '이벤트 루프를 막지 말아라'라는 말의 의미는 '콜 스택에 필요없는 느린 코드를 쌓아서 브라우저가 할일을 못하게 만들지 말아라' 가 되겠다!
끝으로 마이크로 테스크 큐가 일반 테스크 큐보다 우선순위가 높기때문에 마이크로 테스크 큐에 담기는 프로미스가 우선순위가 높다!
*참고 : dev.to/lydiahallie/javascript-visualized-event-loop-3dif
'CodeStates' 카테고리의 다른 글
IM 24일차 (Basic Web Architecture, Ajax) (0) | 2021.02.05 |
---|---|
IM 22일차 (Promise & Async/Await) (0) | 2021.02.02 |
IM 18일차 (Back Tracking) (0) | 2021.01.29 |
IM 13일차 (Graph) (0) | 2021.01.24 |
IM 11일차 (Tree, Binary Search Tree) (0) | 2021.01.24 |