동기 vs 비동기

Judo·2020년 12월 21일
0

동기와 비동기를 다루기 위해선 실행 컨텍스트와 관련하여 함수의 호출부터 실행, 종료까지 어떤 흐름을 갖는지 알아야 합니다.
간단히 서술하자면 함수가 호출된 뒤 함수 실행 컨텍스트가 생성되고, 해당 함수 실행 컨텍스트가 실행 컨텍스트 스택에 푸쉬가 된 뒤 해당 함수가 실행되는 흐름을 갖고 있습니다.

함수 호출 -> 함수 실행 컨텍스트 생성 => 실행 컨텍스트 스택(콜 스택)에 푸쉬 => 함수 실행

위 흐름이 발생할 때 실행 컨텍스트의 모습은 아래와 같습니다.

const foo = () => {};
const bar = () => {};

foo();
bar();

자바스크립트 엔진은 위와 같은 실행 컨텍스트 스택을 단 하나만 갖는데 이를 싱글 스레드 방식으로 동작한다고 합니다.
싱글 스레드 방식은 단 하나의 태스크만 실행할 수 있기 때문에 블로킹이 발생합니다.

동기와 비동기 처리

위에서 설명한 함수와 실행 컨텍스트 스택의 관계, 싱글 스레드 방식과 블로킹을 이해하고 난 뒤 동기와 비동기 처리에 대해 배운다면 좀 더 쉽게 받아들일 수 있는 것 같습니다.(저는..)
동기 처리는 싱글 스레드 방식대로 태스크를 순서대로 하나씩 처리하며, 실행중인 태스크가 있다면 다른 태스크는 블로깅된 상태로 있게 되는 처리 방식입니다. 카페로 예를 들자면 커피를 주문한 손님이 그 커피를 그 자리에서 받아야만 다음 손님이 커피를 주문할 수 있는 상황을 떠올리면 됩니다.
반면 비동기 처리는 실행중인 태스크가 종료되지 않더라도, 다음 태스크를 곧바로 실행하는 방식입니다. 블로깅이 발생하진 않지만 실행 순서가 보장되진 않습니다. 이는 커피를 주문하고 진동벨을 받고 기다리기 때문에 다음 손님이 바로 주문을 할 수 있는 카페를 떠올리면 됩니다.

추가로 얘기하자면 비동기 처리 방식은 보통 콜백 패턴을 사용하는데, 이는 콜백 헬, 어려운 에러 처리, 여러 개의 비동기 처리의 어려움 등이 있기 때문에 프로미스로 이런 문제들을 해결할 수 있습니다.
프로미스는 나중에!

태스크 큐와 이벤트 루프

비동기 처리를 알았으니 브라우저는 '어떻게 비동기 처리를 할까?' 라는 질문에 답해보겠습니다. 브라우저는 자바스크립트 엔진과 태스크 큐, 이벤트 루프를 이용하여 비동기 처리를 수행합니다.
먼저 태스크 큐와 이벤트 루프의 개념을 보자면 태스크 큐는 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이고 이벤트 루프는 콜 스택, 태스크 큐의 상태를 확인하고 태스크 큐에서 콜 스택으로 콜백 함수를 넘겨주는 비동기 처리를 위한 흐름을 얘기합니다.

이벤트 루프를 설명하는 대표적인 그림입니다.

function foo() {}
function bar() {}
setTimeout(foo, 3000);
bar();

위와 같이 코드가 있다고 한다면, foo라는 콜백 함수는 3초 이후 브라우저에 의해 태스크 큐로 push가 됩니다. 그동안 bar는 호출 => 실행의 과정이 지났습니다. 즉 setTimeout이 먼저 호출되었지만 그 안에 foo()가 실행되지 않고 bar() 호출 => 실행이 먼저 됩니다. 이후 콜스택에 실행되는 컨텍스트가 없다면 브라우저는 태스크 큐에서 대기하고 있는 foo를 콜스택에 푸쉬합니다. 따라서 마지막에 foo가 실행되는 방식입니다.

AJAX

AJAX는 자바스크립트를 사용하여 브라우저가 서버에게 비동기 방식으로 데이터를 요청하고, 응답받은 데이터로 웹페이지를 동적으로 갱신하는 프로그래밍 방식입니다. Web API인 XMLHttpRequest 객체를 기반으로 동작합니다.
AJAX의 등장으로 화면 전환 시 서버에서 받은 HTML파일로 다시 렌더링 하는 방식에서 벗어나 변경이 필요한 데이터만 비동기 방식으로 요청하고, 변경이 필요한 부분만 렌더링하는 방식이 자리잡게 되었습니다.

profile
즐거운 코딩

0개의 댓글