<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는
- 즉시 처리하지 못하는 이벤트들을 다른곳(Web API)으로 보내서 처리하도록 하고,
- 처리된 이벤트들은 처리된 순서대로 대기실(Task queue)에 줄을 세워 놓고
- Call Stack이 비면 담당자(Event Loop)가 대기 줄에서 가장 오래된(제일 앞의) 이벤트를Call Stack으로 보냄
- 위 말을 조금 이해하기 쉽게 정리하자면 모든 이벤트 진행은 Call Stack에서 처리가 되고 순차적으로 진행되지 않는 이벤트들은(non-blocking event) web api에서 처리가 된 후 task queue에서 순서를 기다린뒤 event loop가 가장 오래된 이벤트를 처리하기 위해 call stack으로 보내게 된다는 말.
여기서 concurrency model 용어정리
- Call Stack
- 요청이 들어올 때마다 해당 요청을 순차적으로 처리하는 Stack(LIFO)형태의 자료 구조
- Web API(Browser API) (언제 끝날지 모르는 작업들을 처리해줌)
- JS엔진이 아닌 브라우저 영역에서 제공하는 API
- setTimeout(), DOM event 그리고 AJAX로 데이터를 가져오는 시간이 소요되는 일들을 처리
- Task Queue(Event Queue, Message Queue)
- 비동기 처리된 callback 함수가 대기하는 queue(FIFO)형태의 자료 구조
- main thread가 끝난 후 실행되어 후속 JS코드가 차단되는 것을 방지시킴
- Event Loop
- Call Stack이 비어있는지 확인
- 비어있는경우 Task Queue에서 실행 대기 중인 callback 함수가 있는지 확인
- 대기중인 callback함수가 있다면 가장앞에있는 callback함수를 Call Stack으로 push
이러한 비동기를 처리하는대엔 순서가 없으므로 실행순서가 불명확 하다.
이를 해결하기 위해 비동기 처리를 위한 2가지 작성 방식이있다.
- Async callbacks
- 백그라운드에서 실행을 시작할 함수를 호출할 때 인자로 지정된 함수
- ex) addEventListener()의 두번째 인자
- 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 |
댓글