동기와 비동기
동기
Synchronous : 동시에 발생하는
- 순차적/직렬적으로 태스크를 수행한다.
- 요청을 보냈다면, 응답을 받아야 다음 동작이 이루어진다.
- 순차적으로 실행되므로, 어떤 작업이 수행중이라면 뒤의 작업은 대기한다.
- 블로킹(작업 중단)이 발생한다.
비동기
Asynchronous : 동시에 발생하지 않는
- 병렬적으로 태스크를 수행한다.
- 현재 작업의 종료여부와 무관하게 다음 작업을 실행한다.
- 그러므로 동기 방식과는 달리 완료 순서가 보장되지 않는다.
- 블로킹이 발생하지 않는다.
동기 방식은
손님이 주문을 하고 >> 커피가 나올 때 까지 기다려서 >> 커피를 받아야 한다.
비동기 방식은
우선 주문을 받고 >> 손님은 커피가 나오는 순서를 신경쓰지 않고 >> 진동벨이 울리면 커피를 받는다.
실제 카페에서는 겉보기에 "주문을 순서대로 처리하는" 동기 방식처럼 보인다.
사실 비동기와 더 닮아있다고 볼 수 있다.
여러명의 바리스타가, 각각 주문을 처리하면서 순서가 달라질 수 있고
바리스타가 한명이라도, 첫번째 손님이 스무디를, 2,3번째 손님이 커피를 주문했다면
제조가 쉽고 빠른 커피를 먼저 만들면서 순서가 달라질 수 있는 법이다.
자바스크립트는? 동기? 비동기?
자바스크립트가 싱글 스레드 기반으로 프로세스를 처리하는 것은 유명하다.
또한 동기 방식으로 코드를 해석한다고 한다.
맞다. 자바스크립트는 기본적으로 코드를 순차적으로 처리한다.
여기서 "어.. 근데 비동기 비슷한게 가능하지 않나???" 하는 의문이 든다면 👍
먼저 실제 코드에서 비동기를 적용해야 하는 상황부터 생각해보자.
1,2번의 무거운 작업을 수행해야 한다고 가정해본다.
1. 특정 서버에 요청을 보내서 응답을 가져와야 한다.
2. 일정한 시간 뒤에 특정 코드를 수행해야 한다.
이 작업들의 공통점?
빠르게 처리되지 않는다는 것이다. (=마찬가지로, 작업이 언제 끝날지 예측이 힘들기도 하다.)
그래서 무거운 작업은 비동기적으로 요청해두고(어딘가에서 알아서 무거운 작업을 실행하도록 하고),
바로 다음 작업을 수행할 수 있다면 좋은 시나리오로 보인다.
위의 무거운 작업을 동기/비동기로 실행한 경우를 보고 생각해보자!
자바스크립트의 비동기 작업, 이벤트 루프
자바스크립트는 싱글 스레드를 기반으로 동기 방식 으로 작동한다고 했다.
그럼 순차적인 실행이 될텐데, 어떻게 비동기적으로 동작시킬 수 있을까?
아직도 많은 의문부호가 있다.
심지어 싱글스레드라면서 브라우저에서는 여러 작업들이 동시에 실행되고 있으니 말이다.
사실 이해를 돕기 위해선 자바스크립트 런타임 환경도 알아야 하는데, 오늘 학습할 범위 이상이다.ㅠㅠ.
그러니 이벤트 루프를 알아두자.
이벤트 루프 덕분에 비동기 작업을 수행할 수 있다.
코드를 실행하면서 비동기 작업은, "실행해!"라는 명령을 담아 어딘가로 던져진다.
이 "어딘가"가 이벤트 루프이다. 이벤트 루프가 비동기 작업을 담당 및 처리한다.
덕분에 자바스크립트 엔진은
"무거운 작업"을 어딘가에 위임하고, "동기적으로" 바로 다음 코드를 실행할 수 있다.
그리고 언젠가 이벤트 루프에서 작업이 완료되면??
비동기 작업을 만들 때 콜백 함수를 함께 지정하는데, 콜백함수를 가지고 후속 작업을 진행한다.
굉장히 이상한 말들을 보느라 고생했다. 코드를 보면 조금 더 쉽다.ㅎㅎ
비동기 작업의 예시
비동기의 대표 예시로 setTimeout 함수를 간단하게 써봤다.
console.log("Hello");
setTimeout(() => {
console.log("James");
}, 1000);
console.log("World");
이 코드가 모두 동기적으로 동작해야 한다면,,
Hello 출력 -> 1초 기다린 후 James 출력 -> World 출력 이 되어야 한다.
하지만 결과는 다르다.
왜 James가 마지막에 출력되는 것일까?
기본적으로 자바스크립트는 동기적으로(순차적으로) 코드를 실행하기 때문에 순차적인 흐름으로 이해해보자.
1. console.log("Hello") 출력문을 실행한다.
2. setTimeout을 실행한다.
3. setTimeout은 비동기 작업이다. 우선 즉시 실행되고 종료되며 실행 내용이 이벤트루프로 던져진다.
4. 엔진이 바로 다음 코드 console.log("World") 출력문을 실행한다.
5. 이벤트루프에서는 1초 뒤에 콜백함수 ( ()=>{console.log("James"); ) 을 실행한다.
앞서서 다룬 내용만으로는, 이정도 흐름이 파악 가능하다면 훌륭하다.
(사실 내부적으로는 이벤트루프의 상세동작, 콜백큐, 실행컨텍스트.. 등등 더 있다.)
(이 포스팅에선 TMI니, 이어지는 포스팅들에서 볼 수 있다.)
그럼 아래 코드도 예상해보자.
console.log("Hello");
setTimeout(() => {
console.log("James");
}, 4);
console.log("World");
let i = 0;
while (i < 1e9) i++;
console.log("Finish");
4ms(0.004초)뒤에 수행하는 비동기 작업을 만들었다.
뒤에는 while문이 빡세게 돌아가고 있다.
여기서 결과는 3가지 중 하나일텐데,,
- while문에서 변수 i가 더해지는 와중에 James가 출력되고 while문이 끝난 뒤 Finish가 출력된다.
- while문이 다 끝나고 James가 출력되며, 마지막 Finish가 출력된다.
- while문이 다 끝나고 Finish도 실행되고 난 뒤에 James가 출력된다.
우선 맨 마지막이 정답이다.
이어지는 포스팅에서 그 이유와 자바스크립트가 동기, 비동기를 처리하는 방식을 알아보자.👍
이 글을 보는 분들도 나처럼 설레는 마음을 가지고 다음글을 볼 수 있다면 좋겠다!
참고한 사이트
https://poiemaweb.com/js-async
이어지는 글
'JavaScript > theory' 카테고리의 다른 글
[자바스크립트] 비동기로 데이터 가져오기, 콜백 헬 (0) | 2021.08.22 |
---|---|
[자바스크립트] 비동기 작업, 이벤트 루프와 태스크 큐 (1) | 2021.08.22 |
[자바스크립트] enum을 배우고 구현해보자. (0) | 2021.08.02 |
[자바스크립트] XML과 JSON 포맷 배우기 (0) | 2021.08.01 |
[자바스크립트] 일급 객체? 함수! (0) | 2021.07.24 |