[3/13] 동기/비동기 & 이벤트루프

릿·2023년 3월 19일
0

CS스터디

목록 보기
11/18

1. 동기 / 비동기

1. 동기

  • 순차적/직렬적으로 태스크를 수행한다.
  • 요청을 보냈다면, 응답을 받아야 다음 동작이 이루어진다.
  • 순차적으로 실행되므로, 어떤 작업이 수행중이라면 뒤의 작업은 대기한다.
  • 블로킹(작업 중단)이 발생한다.

2. 비동기

  • 병렬적으로 태스크를 수행한다.
  • 현재 작업의 종료여부와 무관하게 다음 작업을 실행한다.
  • 동기 방식과는 달리 완료 순서가 보장되지 않는다.
  • 블로킹이 발생하지 않는다.

3. 비동기적으로 실행되는 것을 동기적으로 코딩하는 방법

  • Promise : 비동기 처리결과를 then과 catch로 동기적으로 사용할 수 있음
  • async/await : ES8에서 간단하고 가독성 좋게 비동기 처리를 동기 처리처럼 구현하기 위해 도입됨. Promise기반으로 동작하며, 후속처리메서드 없이 비동기 함수 앞에 await를 붙이면 동기처럼 사용할 수 있음

2. 이벤트루프

1. 자바스크립트가 비동기처럼 작동하는 방법

1. 자바스크립트에서 비동기가 가능한 이유

브라우저 내장기능 중 하나인 이벤트 루프로 인해 멀티 스레드로 작동하여 비동기 작업이 가능해짐

2. 자바스크립트 엔진의 구성

  • 콜 스택 (call stack) : = 실행 컨텍스트 스택, 함수를 호출하면 함수 실행 컨텍스트가 순차적으로 콜 스택에 푸시되어 순차적으로 실행됨.
    실행 중인 실행 컨텍스트가 종료되어 콜 스택에서 제거되기 전까지는 다른 어떤 태스크도 실행되지 않음
  • 힙 (heap) : 객체가 저장되는 메모리공간으로 실행 컨텍스트는 힙에 저장된 객체를 참조함.
    힙은 구조화 되어 있지 않다는 특징이 있음

3. 브라우저 환경의 구성

  • 태스크 큐 (tast queue, event queue, callback queue) : setTimeout이나 setInterval과 같은 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역
    태스크큐와는 별도로 프로미스의 후속 처리 메서드의 콜백 함수가 일시적으로 보관되는 마이크로태스크 큐도 존재함
  • 이벤트 루프 (event loop) : 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지, 태스크 큐에 대기 중인 함수가 있는지 반복해서 확인하여 콜 스택이 비어있고 태스크 큐에 대기 중인 함수가 있다면 이벤트 루프는 순차적으로(FIFO) 태스트 큐에 대기 중인 함수를 콜 스택으로 이동시킴
  • Web API : Ajax 요청, setTimeout(), 이벤트 핸들러의 등록과 같이 웹 브라우저에서 제공하는 기능들을 일컬음.

4. 태스크 큐

비동기 작업들은 테스크 큐라는 저장공간에 들어가게 된다. 태스크 큐는 발생한 순서대로 큐에 쌓이고 이벤트 루프에 의해 처리되며 태스크큐는 매크로 태스크 큐 와 마이크로 태스크로 구분할 수 있는데, 이 둘의 차이는 처리할 작업의 우선순위이다. 마이크로 태스크는 매크로 태스크 보다 우선순위가 높다.
그렇기 때문에 항상 마이크로태스크의 작업이 더 먼저 처리된다.

5. 매크로 태스크 큐

  • 종류 : DOM 이벤트 콜백, 타이머(setTimeout, setInterval), 스크립트 로딩

5. 마이크로 태스트 큐

  • 종류 : 프로미스 핸들러 (then / catch / finally) + await, Object.observe, process (MutationObserver 등)
  • 마이크로태스크가 모두 처리되기 전까지는 UI 렌더링이나 네트워크 요청은 절대 일어나지 않음

6. 애니메이션 프레임

  • 애니메이션 관련 콜백 함수가 저장되는 큐로, 실행순위 2순위이다.
  • 브라우저의 requestAnimationFrame와 같은 애니메이션의 경우 Animation Callback Queue에서 담당한다. 위와는 별개로 픽셀의 리페인트 이전에 동작하며, 애니메이션 작업중에 들어온 추가적인 작업들은 다음 프레임으로 미루는 방식이다.

1. requestAnimationFrame

  • 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 합니다. 이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받습니다.
  • 부드러운 애니메이션을 위해 사용하고 그러한 기능을 제공한다. 좀더 쉽게 말해 브라우저가 렌더링을 할 수 있을때에 다음 렌더링을 진행할 수 있도록 최적화 해주는 툴과 같다.
  • 새로운 requestAnimationFrame을 생성하면, 이전 것은 반드시 cancelAnimationFrame을 통해 삭제해줘야한다. 안그러면 콜백 리스트에 계속해서 쌓이게된다.
  • 리플로우: 브라우저 화면 상에 무언가를 렌더할 때, 위치나 색을 계산하는 과정
  • 리페인트: 이 계산을 실제로 수행하여 브라우저상에 그리는 것
  • 리페인트 과정이 끝나지도 않았는데 다음 좌표로 이동하라고 애니메이션을 수행하는 경우, 애니메이션이 의도한 대로 부드럽게 움직이지 않게 되는데 이 때 requestAnimationFrame이 문제를 해결해줌
profile
항상 재밌는 뭔가를 찾고 있는 프론트엔드 개발자

0개의 댓글