[자바스크립트] 동기, 비동기

Web/자바스크립트|2022. 10. 26. 11:43

221026 - 동기/비동기

동기

0. 개요

  • 모든 일을 순서대로 하나씩 처리하는 것
  • 순서대로 처리한다 == 이전 작업이 끝나면 다음 작업을 시작한다.
  • 요청과 응답을 동기식으로 처리한다면?
    • 요청을 보내고 응답이 올때까지 기다렸다가 다음 로직을 처리

0-1. 웹에서의 동기 경험하기

<body>
  <button>버튼</button> 
  <script>
    const btn = document.querySelector('button')
    btn.addEventListener('click', () => {
      alert('you clicked me!')
      const pElem = document.createElement('p')
      pElem.innerText = 'p Element'
      document.body.appendChild(pElem)
  })
  </script>
</body>
  • alert 버튼을누르기 전까지 p태그가 보이지 않음

 

비동기

0. 개요

  • 작업을 시작한 후 결과를 기다리지 않고 다음 작업을 처리하는 것
  • 시간이 필요한 작업들은 요청을 보낸 뒤 응답이 빨리 오는 작업부터 처리
  • ex)
    1. Gmail에서 메일 전송을 누르면 목록 화면으로 전환되지만, 실제로 메일을 보내는 작업은 병렬적으로 뒤에서 처리됨
      • 만약 메일 전송이 동기식이라면, 메일 전송이 완료될 때 까지 그 자리에서 움직일 수 없음
    1. 비동기 코드
    function slowRequest(callBack) {
      console.log('1. 오래 걸리는 작업 시작 ...')
      setTimeout(function () {  
        callBack()
      }, 3000)
    }
    
    function myCallBack() {
      console.log('2. 콜백함수 실행됨')
    }
    
    slowRequest(myCallBack) // 여기서 myCallBack을 실행하므로 3번보다 
    												// 2번이 먼저 실행되야 할 것 같지만
    												// setTimeout이 비동기로 실행되어 임시로 밀리므로
    												// 3번이 먼저 실행된다.
    console.log('3. 다른 작업 실행')
    
    // 출력결과
    // 1. 오래걸리는 작업 시작
    // 3. 다른 작업 실행
    // 2. 콜백함수 실행됨

1. 비동기를 사용하는 이유

  • 사용자경험
    • 아주 큰 데이터를 불러온 뒤 실행되는 앱이 있을 때(로딩에 시간이 많이 걸리는) 동기로 처리한다면 데이터를 모두 불러온 뒤에야 앱의 실행 로직이 수행되므로 사용자들이 마치 앱이 멈춘 것과 같은 경험을 겪게 됨
    • 즉, 동기식 처리는 특정 로직이 실행되는 동안 다른 로직 실행을 차단하기 때문에 마치 프로그램이 응답하지 않는 듯한 사용자 경험을 만들게 됨
    • 비동기로 처리한다면 먼저 처리되는 부분부터 보여줄 수 있으므로, 사용자 경험에 긍정적인 효과를 볼 수 있음
    • 이와 같은 이유로 많은 웹 기능은 비동기 로직을 사용해서 구현되어 있음
  • 웹 브라우저 엔진 실행 방식
    • 자바스크립트를 읽고 실행하는 웹브라우저 엔진은 stack과 같이 하나씩 빼는 동기 구조임 때문에, 비동기를 사용하여 오래걸리는 작업을 임시로 stack에서 빼놓고 우선 stack을 다 처리한 다음 비동기 작업을 처리함

자바스크립트의 비동기 처리

1. Single Thread 언어, JavaScript

  • JavaScript는 한 번에 하나의 일만 수행할 수 있는 Single Thread 언어로 동시에 여러 작업을 처리할 수 없음
  • 즉, JavaScript는 하나의 작업을 요청한 순서대로 처리할 수 밖에 없음..!
  • 그러면 어떻게 Single Thread인 JavaScript가 비동기 처리를 할 수 있을까?

2. JavaScript Runtime

  • JavaScript 자체는 Single Thread이므로 비동기 처리를 할 수 있도록 도와주는 환경이 필요함
  • 특정 언어가 동작할 수 있는 환경을 런타임이라 함
  • JavaScript에서 비동기 관련한 작업은 JavaScript의 런타임인 브라우저 또는 Node 환경에서 처리
  • 이 중에서 브라우저 환경에서의 비동기 동작은 크게 아래의 요소들로 구성됨
    1. JavaScript Engine의 Call Stack
    1. Web API
    1. Task Queue
    1. Event Loop

3. 비동기 처리 동작 방식

  1. 모든 작업이 Call Stack으로 들어간다.
  1. 비동기 작업일 경우 Web APIs로 넘긴다
    • Web APIs는 자바스크립트가 아닌 브라우저 엔진이 작업을 처리한다.
    • 이 때 Web APIs로 보낸 작업 중 먼저 끝낸 작업(들어온 순서 상관 없이)을
    • CallBack Queue(Task Queue)로 보낸다.
  1. CallBack Queue(Task Queue)는 FIFO 방식으로
  1. Event LoopCall Stack이 비어 있는 것을 체크하고, Task Queue에서 가장 오래된 작업을 Call Stack으로 보낸다.
    • Task Queue에서 가장 오래된 작업 → Web APIs에서 작업이 끝난 순으로 CallBack Queue(Task Queue)에 들어온 작업

 

  • 브라우저 환경에서의 JavaScript의 비동기는 아래와 같이 처리된다.
    1. 모든 작업은 Call Stack(LIFO)으로 들어간 후 처리된다.
    1. 오래 걸리는 작업이 Call Stack으로 들어오면 Web API로 보내서 처리하도록 한다.
    1. Web API에서 처리가 끝난 작업들은 Task Queue(FIFO)에 순서대로 들어간다.
    1. Event LoopCall Stack이 비어 있는 것을 체크하고, Task Queue에서 가장 오래된 작업을 Call Stack으로 보낸다.

 

  1. Call Stack
    • 요청이 들어올 때 마다 순차적으로 처리하는 Stack(LIFO), 기본적인 JavaScript의 Single Thread 작업 처리
    • 자바스크립트가 제공하는 동기식 처리
  1. Web API
    • 자바스크립트 엔진이 아닌 브라우저에서 제공하는 runtime 환경으로 시간이 소요되는 작업(비동기 작업)을 처리
    • setTimeout, DOM Event, AJAX 요청 등
  1. Task Queue
    • 비동기 처리된 Callback 함수가 대기하는 Queue(FIFO)
  1. Event Loop
    • Call Stack과 Task Queue를 지속적으로 모니터링
    • Call Stack이 비어있는 지 확인 후 비어 있다면, Task Queue에서 대기 중인 오래된 작업을 Call Stack으로 Push

'Web > 자바스크립트' 카테고리의 다른 글

[자바스크립트] 콜백함수와 Promise  (0) 2022.10.26
[자바스크립트] Axios 라이브러리  (0) 2022.10.26
[자바스크립트] this  (0) 2022.10.24
[자바스크립트] event  (0) 2022.10.24
[자바스크립트] DOM  (0) 2022.10.24

댓글()