자바스크립트와 비동기!

img
자바스크립트는 싱글스레드. 한번에 한가지 일 밖에 못한다..!
그런데 어떻게 비동기로 일을 처리하는것일까요?

공부의 결론

  1. 자바스크립트 엔진은 단일 스레드 이지만, 브라우저 환경은 멀티 스레드라 가능하다
  2. 그렇기에 자바스크립트 코드로 비동기 관련된 코드를 쓰면 (web api, http요청) 자바스크립트 엔진은 평가와 실행 이외엔 아무것도 안합니다.
  3. 테스크 큐로 넘겨버리고 이벤트루프가 콜스택에 아무것도 없나 확인하고 없을 시 테스크 큐에 있는 함수를 콜스택에 하니씩 넣어주고 실행합니다. 이게 비동기!

동기와 비동기

자바스크립트 엔진은 한줄씩 코드를 읽는다 -> 함수를 만나면 새로운 실행 컨텍스트가 생성되고 -> 콜스택에 쌓인다. 자바스크립트의 실행 순서입니다. 함수가 실행되려면 그 함수 실행 컨텍스트가 콜 스택에 푸쉬 되어야만 합니다.

여기서 자바스크립트 엔진은 딱 딱 딱 하나의 콜스택을 갖습니다..! 이말은 함수를 실행할수 있는 길이 하나라는것이고 빨래를 돌려놓고 설거지를 할수있는게 아니라 빨래 끝날때까지 기다려야 한다는것입니다. (= 싱글 스레드)

싱글 스레드는 한번에 하나의 테스크만 실행 가능, 따라서 처리시간이 걸리는 경우 블로킹(작업중단)이 발생합니다. (빨래 돌려놓고 다른 집안일 못하고 앞에서 지켜봐야합니다.)

비동기 처리 = 실행중인 테스크 종료여부에 상관 없이 바로 다음 테스크 실행

동기는 순서가 보장된다는 장점이 있지만 앞 테스크가 종료될때 까지 블로킹이 발생합니다. 비동기는 블로킹 없이 쭉 쭉 자기 일 할 수 있지만 순서가 보장되지 않습니다.

비동기처리는 전통적으로는 콜백을 많이 사용했는데, 예외처리의 문제와 여러개의 비동기 처리가 한계가 있고 무엇보다 가독성이,, 쉽지가 않습니다. 그렇기에 비동기 처리시에는 포로미스라는 약속된 객체를 많이 사용합니다.

자바스크립트에서 볼 수 있는 비동기처리는 타이머함수인 setTimeout, HTTP요청, 이벤트 핸들러등이 있습니다.

이벤트 루프와 테스크 큐

자바스크립트는 싱글쓰레드…!

한번에 하나의 요청만 처리해야되는데 그렇다면 브라우저에서 파일 하나 받을때마다 화면이 멈추고 해야되는데 그건 또 아니지요 ,, 이렇듯 자바스크립트의 동시성을 지원하는것은 바로 바로 이벤트 루프!

동시성 : 멀티 태스킹을 위해 여러 개의 스레드가 '번갈아가면서' 실행되는 성질. 정말 물리적으로 동시에 동작하는 것은 아님. 싱글 코어에서 멀티스레드를 동작시키기 위한 방식

이벤트 루프는 브라우저에 내장된 기능 중 하나 (web api)

브라우저 환경에는 자바스크립트 엔진과 테스크 큐 이벤트 루프가 있습니다.

자바스크립트 엔진은 크게 두가지 영역으로 구분되는데 힙과 스택!

  1. 콜스택

    • 실행컨텍스트가 추가되고 제거되는 스택 자료구조
    • 함수를 호출하면 함수 실행컨텍스트가 순차적으로 콜스택에 푸시, 순차적으로 실행됨
    • 자바스크립트 엔진은 딱 하나의 콜 스택만 사용

  2. 힙 - 객체가 저장되는 메모리 공간 - 실행 컨텍스트는 힙에 저장된 객체를 참조

콜스택과 힙으로 구성된 자바스크립트 엔진은 테스크가 요청될 시 콜스택으로 요청된 작업을 순서대로 처리!

비동기 처리 시 실행및 평가 빼고는 자바스크립트 구동 환경인 브라우저 및 Node.js가 담당합니다. 브라우저 환경은 비동기 처리를 위해 테스크 큐와 이벤트 루프를 제공합니다.

  1. 테스크 큐

    • 비동기로 처리가 필요한 콜백함수나 이벤트 핸들러가 일시적으로 보관되는 영역
    • 마이크로테스크 큐(우선순위 높음)도 존재
  2. 이벤트 루프

    • 실행중인 실행컨텍스트가 있나 테스크 큐에 대기중인 함수가 있나를 반복 확인 (그래서 루프)
    • 콜스택 비어있을 시 순차적으로 테스크 큐에 대기중인 함수를 콜스택으로 이동시킴



참고한 곳

https://beststar-1.tistory.com/24<br> 자바스크립트 딥다이브


Written by@[Wookchang Lee]
프론트엔드 새싹 프론트엔드 꿈나무

GitHub