너무 좋은 영상인 what is event loop anyway 를 보고 정리하는 글입니다.
싱글스레드 언어라는 것은, call stack 콜 스택이 하나 있다는 것을 의미합니다. (싱글스레드란, 한번에 하나만 실행할 수 있다는 의미니까요)
함수가 있을 때 흐름은 다음과 같습니다.
에러가 날 때도 스택 순서대로 에러가 나는 것을 확인할 수 있습니다(..솔직히 크게 신경쓴 적이 없었는데..ㅠ 신경쓴 사람은 손을 들어주세요 🙋♀️)
function foo(){
throw new Error('Oops')
}
function bar(){
foo()
}
function baz(){
bar()
}
baz()
코드 흐름을 생각해보면 이렇습니다.
1.baz()
가 호출된다. baz()
가 콜스택에 쌓인다.
2.bar()
이 호출된다. bar()
이 콜스택에 쌓인다.
3.foo()
가 호출된다. foo()
가 콜스택에 쌓인다.
4.foo()
는 Error
를 반환한다.
스택에 차곡차곡 쌓여있는 콘솔 메세지를 볼 수 있습니다. 마지막에 보이는 anonymous function
는 메인함수입니다.
만일 함수를 이렇게 호출한다면 우리가 가끔씩은 만났던 에러메시지를 볼 수가 있습니다. 그것은 바로 !!
RangeError : Maximum call stack size exceeded
function foo(){
return foo()
}
foo()
foo()는 또 foo()를 호출하고, 또 foo()를 호출하고... 결국 콜 스택의 사이즈를 벗어나게 되는 것이죠
stack에 느린 작업이 있다면 시간이 오래걸리기 때문에 blocking이 됩니다. 이게 문제가 되는 이유는 우리가 브라우저를 사용하기 때문입니다.
콜스택에 작업이 쌓여있다면, 브라우저는 아무 작업을 할 수가 없습니다. 렌더링을 하지 못하게 됩니다.
그럼 이것의 해결책으로는 무엇이 있을까요? 바로 async callback을 활용하는 것입니다.
다음의 경우 어떤식으로 흘러갈까요?
console.log('hi')
setTimeout(()=> {
console.log('there')
},5000)
console.log('JSConfEU')
순서는 다음과 같습니다.
console.log('hi')
setTimeout()이 Stack에 들어갔다가 사라짐
console.log('JSConfEU')
5초 뒤에 console.log('there')
자바스크립트는 런타임동안 한가지 일을 할 수 있지만, 브라우저는 Web API와 같은 다른 것들을 우리에게 제공해줍니다.
이벤트 루프는 먼저 스택을 확인합니다. 그리고 스택이 비어있다면 테스크 큐의 가장 처음에 있는 작업을 꺼내어 스택에 넣어줍니다(push)
setTimeout
을 0초 뒤에 실행하더라도 결과는 같습니다. 왜냐면 테스크 큐의 작업은 결국 스택이 비어있어야 하나씩 스택에 들어가기 때문입니다.