본문 바로가기
JavaScript

비동기식 코드

by 갈잃자 2022. 5. 3.
<script>
  const request = new XMLHttpRequest() // XMLHttpRequest 함수를 실행
  const URL = 'https://jsonplaceholder.typicode.com/todos/1' // 쓰여질 url

  request.open('GET', URL) // 브라우저 검색창에 get형태로 url올려놓고 대기상태
  console.log('start')
  request.send() // 보내기
  const todo = request.response //응답을 todo라는 변수에 대입
  console.log('end')
  </script>

위 코드를 보면 2줄까진 동기식으로 진행이 되었다가 request.send()쪽에선 비동기식으로 작동된다. 또 그 아래 두 코드는 다시 동기식인걸 알 수 있다.

 

이러한 비동기식을 사용하는 이유가 무엇인가?

비동기식 코드라면 데이터를 요청하고 응답 받는 동안,
 앱 실행을 함께 진행함으로써 더욱 쾌적한 '사용자 경험'을 제공한다.

이에 필요한 개념을 설명해 보자면

Threads

  • 프로그램이 작업을 완료하기 위해 사용할 수 있는 단일 프로세스
  • 각 thread는 한 번에 하나의 작업만 수행할 수 있음
  • 브라우저에선 1탭당 1명의 일꾼이라 생각하면 됨.

blocking vs non-blocking

ex)

# blocking

import requests
URL = 'https://jsonplaceholder.typicode.com/todos/1'
print('start')
res = requests.get(URL).json()
print('end')

python 인경우 start를 출력하고 res에서 변수를 할당 후 end가 출력이 된다.
- 하나의 순서가 끝나기 전까진 다음 순서가 진행이 되지 않음
const request = new XMLHttpRequest()
  const URL = 'https://jsonplaceholder.typicode.com/todos/1'

  request.open('GET', URL)
  console.log('start')
  request.send()
  const todo = request.response
  console.log('end')

ajax의 경우 순차적으로 start가 출력이 된 후 request.send() 가 진행이 끝나기전,
실행만 시켜놓고 end를 미리 출력 후 시간이 지난 후에 request.send()메서드가 진행된다.

 

"javaScript는 single threaded이다."

  • 컴퓨터가 여러 개의 CPU를 가지고 있어도 main thread라 불리는 단일 스레드에서만 작업 수행을한다. 즉 이밴트를 처리하는 Call Stack이 하나인 언어라는 의미.
  • 이 문제를 해결하기 위해 javaScript는
  1. 즉시 처리하지 못하는 이벤트들을 다른곳(Web API)으로 보내서 처리하도록 하고,
  2. 처리된 이벤트들은 처리된 순서대로 대기실(Task queue)에 줄을 세워 놓고
  3. Call Stack이 비면 담당자(Event Loop)가 대기 줄에서 가장 오래된(제일 앞의) 이벤트를Call Stack으로 보냄
  • 위 말을 조금 이해하기 쉽게 정리하자면 모든 이벤트 진행은 Call Stack에서 처리가 되고 순차적으로 진행되지 않는 이벤트들은(non-blocking event) web api에서 처리가 된 후 task queue에서 순서를 기다린뒤 event loop가 가장 오래된 이벤트를 처리하기 위해 call stack으로 보내게 된다는 말.

 

여기서 concurrency model 용어정리

  1. Call Stack
    • 요청이 들어올 때마다 해당 요청을 순차적으로 처리하는 Stack(LIFO)형태의 자료 구조
  2. Web API(Browser API) (언제 끝날지 모르는 작업들을 처리해줌)
    • JS엔진이 아닌 브라우저 영역에서 제공하는 API
    • setTimeout(), DOM event 그리고 AJAX로 데이터를 가져오는 시간이 소요되는 일들을 처리
  3. Task Queue(Event Queue, Message Queue)
    • 비동기 처리된 callback 함수가 대기하는 queue(FIFO)형태의 자료 구조
    • main thread가 끝난 후 실행되어 후속 JS코드가 차단되는 것을 방지시킴
  4. Event Loop
    • Call Stack이 비어있는지 확인
    • 비어있는경우 Task Queue에서 실행 대기 중인 callback 함수가 있는지 확인
    • 대기중인 callback함수가 있다면 가장앞에있는 callback함수를 Call Stack으로 push

이러한 비동기를 처리하는대엔 순서가 없으므로 실행순서가 불명확 하다.

이를 해결하기 위해 비동기 처리를 위한 2가지 작성 방식이있다.

  1. Async callbacks
    • 백그라운드에서 실행을 시작할 함수를 호출할 때 인자로 지정된 함수
    • ex) addEventListener()의 두번째 인자
  2. promise-style
    • Modern Web API에서의 새로운 코드 스타일
    • XMLHttpRequest 객체를 사용하는 구조보다 조금 더 현대적인 버전

 

 

'JavaScript' 카테고리의 다른 글

array(배열)을 변형시키는 내장함수들  (0) 2022.09.20
형변환, typeof  (1) 2022.09.18
삼항연산자  (0) 2022.09.17
Axios  (0) 2022.05.03
XMLHttpRequest  (0) 2022.05.03

댓글