♻️ 개발자로 재활용/🟢 JavaScript

동기(Synchronous)와 비동기(Asynchronous)

BuleRatel 2022. 11. 24. 00:10
혼자서 이해하기 위해 쉽게 풀어쓰다보니 오류가 있을 수도 있습니다! 틀린 내용이 있다면 말씀 주세요.

 

 

 


동기와 비동기

동기와 비동기는 일종의 수행 방식의 차이입니다. 어떠한 일을 동기적으로 처리한다, 비동기적으로 처리한다라고 이해해주시면 될 것 같아요. 컴퓨터 공학에서 동기적인 방식과 비동기적 방식이 어떻게 이루어지는지 알아봅시다.

 

📌 동기(Synchronous)

동기적인 방식은 요청과 결과가 순차적으로 일어납니다. 1번 요청→1번 대한 결과→2번 요청→2번에 대한 결과→(…) 이런 식으로 일을 수행하죠. 순서대로 일이 수행되니 설계 방식이 비교적 간단하고 직관적입니다. 하지만 어떠한 요청에 수행 시간이 오래 걸린다면 어떻게 될까요? 결과가 나오기 전까지 다음 요청들은 모두 대기를 해야 할 겁니다.

 

 

📌 비동기(Asynchronous)

이와 대조적으로, 비동기적인 방식은 현재 작업 여부와 무관하게 다음 작업을 실행하고, 완료합니다. 1번, 2번, 3번 요청을 동시다발적으로 수행한 뒤 먼저 완료된 결과부터 내보내지요. 동기에 비해 설계가 복잡할 테지만, 불필요한 대기 없이 요청을 수행할 수 있으므로 효율적입니다.

 

 

 

우리가 웹페이지를 사용할 때를 생각해 봅시다. 한 페이지에서 여러 작업이 가능합니다. 즉, 비동기적인 수행이 가능합니다. 유튜브 재생창을 한번 예를 들어 볼게요. 동영상이 로드되고 있는 동안에도 댓글을 달거나, 검색창에 글씨를 쓰거나, 다른 비디오에 커서를 올려 재생을 시킬 수 있습니다.

 

웹 개발에서 비동기적 실행(Asynchronous execution)이라는 개념은 특히 유용합니다. 동영상이 모두 로드되고 나서야 다른 작업을 할 수 있다고 생각해 보세요. 기다리다 못한 사용자들이 모두 이탈할 것입니다. 특히, 아래 작업은 비동기적으로 작동되어야 효율적입니다.

  • 백그라운드 실행, 로딩 창 등의 작업
  • 인터넷에서 서버로 요청을 보내고, 응답을 기다리는 작업
  • 큰 용량의 파일을 로딩하는 작업

 

 

 


JavaScript에서 동기와 비동기

사실 자바 스크립트는 ‘싱글 스레드(Single Thread)’ 언어입니다. 싱글 스레드라는 단어에서 유추해 낼 수 있듯, 순차적으로 실행한 코드를 실 하나처럼 이어놓은 것이죠. 한 번에 한 가지 일밖에 하지 못한다는 의미입니다.

 

📌 그런데 앞서 예시로 든 유튜브 화면은 비동기적 방식으로 수행되고 있지 않았나요?

웹브라우저의 자바 스크립트 코드는 브라우저를 실행시킨 순간 순차적으로 실행됩니다. 너무 빨라 동시에 실행되는 것처럼 보이고요(몇몇 무거운 코드들은 좀 느리겠지만요). 화면에만 보이지 않을 뿐, 댓글을 입력하는 코드와 검색창에 글씨를 쓰는 코드들도 모두 자바 스크립트상에 존재하고 실행된 상태입니다. 하지만 실행시킨 코드가 모두 순서대로 출력된다면 의도치 않은 결과가 발생할 겁니다. 어떤 코드들은 ‘검색’버튼을 누른 다음에 실행되어야 하는 것처럼요.

 

때문에 이미 실행된 코드들에 보조적인 장치를 더해 실행될 ‘순간’을 지정해 줍니다. 웹페이지는 전체적으로 ‘비동기적 수행’을 하는 것처럼 보이지만, 특정 부분들은 순서를 정해 ‘동기적’으로 수행하게 만드는 것이죠. DOM에서 addEventListener를 사용했던 것을 생각해 봅시다.

document.querySelector('#btn').addEventListener('click', function(el) {
	console.log('click');
}

// 어딘가 구현되어 있을 id='btn'인 element를 찾아,
// 'click'하면
// console.log('click')이라는 함수를 실행시킨다
// 즉, click을 통해 코드를 순차적으로 실행시킨다.

 

 

 


JS의 비동기적 수행을 도와주는 것들

JavaScript runtime(자바스크립트 런타임)에 대해 간단하게 짚고 넘어가 봅시다. 런타임이란 ‘프로그래밍 언어가 구동되는 환경’을 말합니다. 흔히 사용하는 크롬, 사파리, 웨일 브라우저 등의 여러 브라우저들이 바로 자바 스크립트의 런타임입니다. 앞으로 배울 Node.js 역시 자바 스크립트를 구동하는 비동기 이벤트 기반 런타임입니다.

  • runtime : 프로그래밍 언어가 구현되는 환경
  • JavaScript runtime : 브라우저(크롬, 사파리 등), Node.js

자바 스크립트는 싱글 스레드 언어지만, 런타임이 가지고 있는 ‘API(Application Programming Interface)’들이 상황을 ‘비동기’로 구현할 수 있게 도와줍니다. DOM을 생각해 보세요. DOM 뿐만 아니라 앞으로 배울 setTimeout()과 setInterval() 함수, AJAX(HTTP 요청)도 이런 Web API입니다. (MDN의 Web API 목록을 참고해 보세요)

 

  • DOM Element의 이벤트 핸들러
    • 마우스 클릭이 이루어 졌을 때, 키보드 타이핑을 시작했을 때 등 (click, keydown envet)
    • 페이지가 로딩되었을 때 (DOMContentLoaded 등)
  • 타이머
    • 타이머 API (setTimeout 참고하기)
    • 애니메이션 API (requestAnimationFrame)
  • 서버에 자원 요청 및 응답 (가장 많이 쓰임!) : 날씨, 버스 도착 등을 구현
    • fetch API
    • AJAX (XHR)

 

또는 ‘함수’를 통해 비동기적 방식을 수행하기도 합니다. 특정 함수가 실행되고 나서야 실행되는 함수처럼요. 이때 유용하게 쓰이는 방식이 callback 함수입니다. 이제 callback 함수가 어떻게 비동기 코드의 작동 순서를 제어하는지, 그리고 callback 함수를 보완한 Promiseasync/await에 대해서도 알아봅시다.

 

 

 

 

참고 자료