728x90
목차
- 동기
- 비동기
- Javascript의 비동기 처리
- blocking과 non-blocking
1. 동기(Synchronous)
- 모든 일을 순서대로 하나씩 처리하는 것
- 순서대로 처리한다 == 이전 작업이 끝나면 다음 작업을 시작한다.
- 즉, 함수 A가 B를 호출한 뒤, 함수 B의 리턴값을 계속 확인하면서 신경쓰는 것
- B의 리턴값이 필요하다라고 볼 수 있다.
- 지금까지 작성했던 Python 코드가 작동되는 것이 동기식
- 이 때, 코드가 아래로 진행되지 못하는 것은 -> block
- 즉, 요청을 보내고 응답이 올때까지 기다렸다가 다음 로직을 처리한다.
- 웹에서의 동기 - 확인을 누르기전까지 p태그는 보이지 않는다.
2. 비동기(Asynchronous)
- 작업을 시작한 후 결과를 기다리지 않고 다음 작업을 처리하는 것 (병렬적 수행)
- 시간이 필요한 작업들은 요청을 보낸 뒤 응답이 빨리 오는 작업부터 처리
- 즉, 함수 A가 B를 호출할 때 콜백 함수를 함께 전달해서, 함수 B의 작업이 완료되면 함께 보낸 콜백 함수를 실행
- A는 B를 호출한 후로 함수 B의 작업 완료 여부에는 신경쓰지 않는다.
- 예) Gmail에서 메일 전송을 누르면 목록 화면으로 전환되지만 실제로 메일을 보내는 작업은 병렬적으로 뒤에서 처리된다!
비동기(Asynchronous)를 사용하는 이유
- 사용자 경험
- 예를 들어 아주 큰 데이터를 불러온 뒤 실행되는 앱이 있을 때, 동기로 처리한다면 데이터를 모두 불러온 뒤에야 앱의 실행 로직이 수행되므로 사용자들은 마치 앱이 멈춘 것과 같은 경험을 겪게 됨
- 즉, 동기식 처리는 특정 로직이 실행되는 동안 다른 로직 실행을 차단하기 때문에 마치 프로그램이 응답하지 않는 듯한 사용자 경험을 만들게 됨
- 비동기로 처리한다면 먼저 처리되는 부분부터 보여줄 수 있으므로, 사용자 경험에 긍정적인 효과를 볼 수 있음
- 이와 같은 이유로 많은 웹 기능은 비동기 로직을 사용해서 구현되어 있음
3. JavaScript의 비동기 처리
Single Thread 언어, JavaScript
- 그렇다면 응답이 먼저 오는 순서대로 처리하지 말고, 아예 여러 작업을 동시에 처리하면 되지 않을까?
- JavaScript는 한 번에 하나의 일만 수행할 수 있는 Single Thread 언어로 동시에 여러 작업을 처리할 수 없음
- 참고 - Thread란?
- 작업을 처리할 때 실제로 작업을 수행하는 주체로, multi-thread라면 업무를 수행할 수 있는 주체가 여러 개라는 의미
- 즉, JavaScript는 하나의 작업을 요청한 순서대로 처리할 수 밖에 없다.
- 그렇다면 Single Thread인 JavaScriopt가 비동기 처리를 할 수 있을까?
JavaScript Runtime
- JavaScript 자체는 Single Thread이므로 비동기 처리를 할 수 있도록 도와주는 환경이 필요함
- 특정 언어가 동작할 수 있는 환경을 런타임(Runtime)이라 함
- JavaScript에서 비동기와 관련한 작업은 브라우저 또는 Node 환경에서 처리
- 이 중에서 브라우저 환경에서의 비동기 동작은 크게 아래의 요소들로 구성됨
- JavaScript Engine의 Call Stack
- Web API
- Task Queue
- Event Loop
비동기 처리 동작 방식
- 브라우저 환경에서의 JavaScript의 비동기는 아래와 같이 처리된다.
- 모든 작업은 Call Stack(LIFO)으로 들어간 후 처리된다.
- 오래 걸리는 작업이 Call Stack으로 들어오면 Web API로 보내서 처리하도록 한다.
- Web API에서 처리가 끝난 작업들은 Task Queue(FIFO)에 순서대로 들어간다.
- Event Loop가 Call Stack이 비어 있는 것을 체크하고, Task Queue에서 가장 오래된 작업을 Call Stack으로 보낸다.
- Call Stack
- 요청이 들어올 때 마다 순차적으로 처리하는 Stack(LIFO)
- 기본적인 JavaScript의 Single Thread 작업 처리
- Web API
- JavaScript 엔진이 아닌 브라우저에서 제공하는 runtime 환경으로 시간이 소요되는 작업을 처리 (setTimeout, DOM Event, AJAX 요청 등)
- Task Queue
- 비동기 처리된 Callback 함수가 대기하는 Queue(FIFO)
- Event Loop
- Call Stack과 Task Queue를 지속적으로 모니터링
- Call Stack이 비어 있는지 확인 후 비어 있다면 Task Queue에서 대기 중인 오래된 작업을 Call Stack으로 Push
4. blocking과 non-blocking
우선 알고 넘어가야 할 용어 2개
- 제어권
- 제어권은 자신(함수)의 코드를 실행할 권리 같은 것
- 제어권을 가진 함수는 자신의 코드를 끝까지 실행한 후, 자신을 호출한 함수에게 돌려준다.
- 결과값을 기다린다는 것
- A 함수에서 B 함수를 호출했을 때, A 함수가 B 함수의 결과값을 기다리느냐의 여부를 의미
블로킹
- 블로킹은 A 함수가 B 함수를 호출하면, 제어권을 A가 호출한 B 함수에 넘겨준다.
논블로킹
- 논블로킹은 A 함수가 B 함수를 호출해도 제어권은 그대로 자신이 가지고 있는다.
※ 참고 - blocking과 synchronous
- A는 함수 B의 리턴값을 필요로 한다(동기)
- 그래서 제어권을 함수 B에게 넘겨주고, 함수 B가 실행을 완료하여 리턴값과 제어권을 돌려줄때까지 기다린다(블로킹)
※ 참고 - non-blocking과 synchronous
- A 함수는 B를 호출
- 이 때, A 함수는 B 함수에게 제어권을 주지 않고, 자신의 코드를 계속 실행 (논블로킹).
- 그런데 A 함수는 B 함수의 리턴값이 필요하기 때문에, 중간 중간 B 함수에게 함수 실행을 완료했는지 물어본다.(동기)
※ 참고 - blocking과 asynchronous
- 보기 힘든 유형
- A 함수는 B 함수의 리턴값에 신경쓰지 않고, 콜백함수를 보낸다 (비동기)
- 그런데, B 함수의 작업에 관심없음에도 불구하고, A 함수는 B 함수에게 제어권을 넘긴다. (블로킹)
- 따라서, A 함수는 자신과 관련 없는 B 함수의 작업이 끝날 때까지 기다려야 한다.
※ 참고 - non-blocking과 asynchronous
- A 함수는 B 함수를 호출
- 이 때, 제어권을 B 함수에 주지 않고, 자신이 계속 가지고 있는다 (논블로킹)
- 따라서 B 함수를 호출한 이후에도 멈추지 않고 자신의 코드를 계속 실행한다.
- 그리고 B 함수를 호출할 때 콜백함수를 함께 준다. B 함수는 자신의 작업이 끝나면 A 함수가 준 콜백 함수를 실행한다. (비동기)
blocking과 non-blocking 태그 참고 사이트 - https://velog.io/@nittre/%EB%B8%94%EB%A1%9C%ED%82%B9-Vs.-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9-%EB%8F%99%EA%B8%B0-Vs.-%EB%B9%84%EB%8F%99%EA%B8%B0
728x90
'Programming Language > JavaScript' 카테고리의 다른 글
[JS] Callback과 Promise (0) | 2022.10.26 |
---|---|
[JS] Axios 라이브러리 (0) | 2022.10.26 |
[JS] 대화 상자 (0) | 2022.10.25 |
[JS] this (0) | 2022.10.24 |
[JS] Event (0) | 2022.10.24 |