한줄 한줄씩 코드를 읽어나가기 때문에 시간이 엄청 오래걸리는 코드가 있는 경우,
그 아래 있는 코드는 오래 걸리는 코드가 끝날 때까지 기다려야한다.
일반적인 프로그래밍은 순서대로 실행되므로 코드가 동기적
으로 실행된다고 할 수 있다.
마우스 이벤트 등이 발생해야 하는 경우 이벤트가 동기적
으로 실행된다고 가정해보자.
언제 마우스 이벤트가 일어날지 예측할 수 있는가?
지금 당장 일어날 수도, 아예 일어나지 않을 수도 있다.
이벤트가 동기적으로 처리되었다면 이벤트 다음에 있는 코드는 언제 실행될지 기약할 수 없게 되는 문제가 발생할 수 있다. 이때 이러한 문제를 해결할 수 있는 방법으로 비동기
가 있을 것이다.
앞서 동기의 문제점에서 이벤트를 예시로 들 수 있었다.
이벤트 발생만을 위해서 기다린다니.. 약간 낭만적인 것 같지만 현실은 그렇지 않다.
밥을 먹으러 갔는데 앞 사람이 다 먹어야 내가 먹을 수 있는 상황을 생각해보자.
앞 사람이 끝까지 테이블에 앉아서 나오지 않는다면..? 언제 나올지 기약이 없다면..?
매우 화가 날지도 모르겠다. 현실이니 다른 밥집을 찾아가는 방법도 있겠지만,
원래 이런건 약간 과장해서 극단적인 상황을 예시로 들면 기억하기 좋다.
이벤트가 발생하는 경우, 비동기로 처리하게 되면다음의 문제를 해결할 수 있게 된다.
자바스크립트가 비동기 코드(이벤트 등)를 만나게 되면 이 코드가 끝날 때까지 기다리지 않고 바로 다음 코드를 실행하게 될 것이다.
예를 들어, 코드가 한줄 한줄씩 읽어 내려가면서 클릭 이벤트 코드를 만나게 되었지만,
아직 클릭 이벤트가 아직 실행되지 않았다면? 동기처럼 이벤트가 실행되기만을 기다리지 않는다.
동기보다는 효율적으로, 어쩌면 매정할 수도 있는 비동기는
이벤트를 등록만 한 채 다음 코드로 넘어간다는 특징
이 있다.
자바스크립트는 싱글 스레드(한번에 하나의 일만 수행)로 동작하기 때문에 한번에 한 줄의 코드만 읽을 수 있다고 하던데요? 사실 비동기 작업은 브라우저의 힘을 빌려야 한다.
브라우저 Web API
덕분에 비동기 작업이 가능하다고 할 수 있을 것이다.
비동기 코드를 만나게 된다면 비동기 코드는 백그라운드로 보내지고 작업이 완료됐을 때 태스크 큐로 보내지게 된다. 앞서 클릭 이벤트 예시를 다시 떠올려보면 처음 코드를 만났을 때 이벤트를 등록만 해놓고 완료되면 태스크 큐로 보낸다는 것이다.
작업을 완료해서 태스크 큐에 줄 서 있는 비동기 코드들을 이벤트 루프가 순서대로 콜스택으로 다시 돌려보낸다.
이때 호출 스택이 비워져 있는 경우에만 태스크 큐에 있는 비동기 코드들이 콜스택에 올라갈 수 있다.
즉, 호출 스택이 모두 비워졌을 때 비로소 태스크 큐에 줄서있는 비동기 코드들이 하나씩 실행되게 된다는 것이다.
참고로 태스크 큐의 줄은 비동기 코드의 일이 끝난 순서가 아닐 수도 있다.
얘네들 끼리도 우선 순위가 있어서 이벤트 루프가 정해주는 순서에 따라 줄을 선다.
예를 들면, 콜백함수(setTimeout 등)보다 프로미스의 then이 더 우선순위라서 동시에 끝났더라도 프로미스(then)가 더 먼저 콜스택으로 불려나간다.
자바스크립트에서 비동기 코드는 Promise(then), async await, 콜백함수 등이 해당된다.
참고 자료
Introducing asynchronous JavaScript
Javascript 동작원리 (Single thread, Event loop, Asynchronous)