비동기에 대해 자세하게 알아보도록 하겠습니다.
우선, 비동기라는 말은 동기 의 반대말로 동시에 움직인다 / 그렇지 못한다 의 개념 보다 순서의 문제에 가깝습니다. 위에서 아래로, 왼쪽에서 오른쪽으로 코드가 진행되는 동기 코드에 반면해 비동기 코드는 코드는 정해진 순서는 있지만, 보이는 순서와 다릅니다. 때문에 비동기 코드는 동시의 개념보다 순서의 문제라고 말할 수 있습니다.
또한. 비동기에 대한 오해 중 하나가 대부분 사람들은 비동기 코드를 동기 코드로 바꾸려는 시도를 합니다. 그래서 promise 코드를 동기 코드로 바꾸기 위해 async / await 을 사용합니다. 사실 이는 동기 코드로 바꾸는 것이 아닙니다. 한번 비동기 코드로 된 것은 쭉 비동기 코드인 것입니다. 비동기 코드를 동기 코드로 바꿀 수 없다는 것을 인정하고, 비동기 코드를 얼마나 효율적으로 짤 수 있는지에 대해 집중해야 합니다.
여기까지 비동기에 대한 개념을 익혔고, 예제를 통해 이벤트 루프를 그려보며 설명해보겠습니다.
setTimeout(() => {
console.log('a');
}, 0);
setTimeout(() => {
console.log('b');
}, 1000);
setTimeout(() => {
console.log('c');
}, 2000);
다음과 같이 그려볼 수 있습니다.
처음 동작으로 호출 스택에 setTimeout 이 하나씩 쌓이고 지워지면서 백그라운드에 console.log 도 하나씩 추가됩니다.
그리고, 백그라운드에 들어온 순서대로 태스크 큐에 쌓이게 되고, 큐(Queue) 의 특성, FIFO(First In First Out) 상 먼저 들어온 순서대로 호출 스택에 쌓일 겁니다. 호출 스택에 쌓이는 역할이 곧 이벤트 루프의 역할이기도 합니다. 하지만, 태스크 큐에서 호출 스택에 쌓이게 되야 할 조건이 하나 있는데, 호출 스택에 있는 함수의 호출이 모두 종료가 된 시점에서 옮겨질 수 있습니다.
setTimeout 함수 3개가 모두 종료되어 annoumous 도 함께 종료되었으므로 호출 스택에 있는 함수가 모두 종료되어 호출 스택은 비어 있게 돼 태스크 큐에 있는 함수들이 하나씩 호출돼고, 다시 호출스택에서 함수를 실행한 뒤 호출스택은 비게 돼어 다시 태스크 큐에서 호출 스택으로 쌓게 되기를 태스크 큐에 있는 함수들이 없어질 때까지 반복합니다.
위와 같은 과정은 자바스크립트 공식 스펙엔 없는 개념이지만, 이 과정을 거쳐 비동기 코드를 분석할 수 있게 되면 왠만한 비동기 코드는 동기 코드처럼 익혀질 것입니다. 처음에 말했던 동시의 개념보다 순서의 개념이 더 가깝다는 이야기가 여기에 해당됩니다.
'zerocho > 인간 JS 엔진 되기(JS 고급 강좌)' 카테고리의 다른 글
Promise 의 동기 부분 (0) | 2023.03.23 |
---|---|
비동기 (micro task queue, macro task queue) (0) | 2023.03.23 |
promise 장점 (0) | 2023.03.22 |
Promise, async / await (0) | 2023.03.22 |
블록 스코프와 매개변수 (0) | 2023.03.21 |