학습 동기
react/ next 프레임 워크를 공부하면서 자주 등장하는 async/await 작동방식에 대한 이해를 돕기 위해 공부한 내용을 적었으며 동기/비동기에 대한 개념과 프로미스 개념 부분은 생략하였습니다.
자바스크립트가 코드를 처리하는 방식
- 자바스크립트 엔진은 스택과 힙으로 구성되고 실행 컨텍스트들이 스택에서 처리됩니다.
- 자바스크립트는 싱글 스레드로 프로세스를 처리하며 동기방식으로 코드를 해석하고 순차적으로 처리합니다.
<예제>

<실행 결과>

- 전역 컨텍스트가 자바스크립트 스택에 저장된다.
- 스택에 저장된 전역 컨텍스트의 코드를 순차적으로 처리한다.
- console.log("hi") 실행
- console.log("hello") 실행
- console.log("bye") 실행
비동기적 처리 방식
- 브라우저와 node.js에는 이벤트 루프와, 테스크 큐, 마이크로 테스크 큐 존재
- 테스크 큐, 마이크로 테스크 큐는 비동기 함수들의 콜백함수를 저장하지만 마이크로 테스크 큐가 우선순위가 더 높으며 프로미스를 다루는 .then, finally, .catch 등이 task로 저장됩니다.
- 자바스크립트는 비동기 함수를 만나면 스택에서 바로 pop하여 콜백함수를 이벤트 루프에 전달합니다. 이벤트 루프는 콜백함수를 큐에 push 하여 저장한 후 자바스크립트 스택이 비워져있는지 확인한 후 비워졌을때 큐에서 꺼내 스택에 저장 시킵니다.
- 즉, 자바스크립트 엔진은 동기적으로 처리하다가 비동기 함수를 만나면 이벤트 루프에 처리를 요청 하고 계속 순차적으로 코드를 처리합니다.
<예제>

실행 결과

- 스택에 전역 컨텍스트 저장
- 전역 컨테스트에 있는 코드들이 순차적으로 처리
- console.log("hi") 실행
- setTimeout 비동기 함수를 만나 스택에서 바로 pop 하여 콜백함수를 이벤트 루프에 전달 -> 이벤트 루프에서 처리되어 큐에 저장 후 대기
- console.log("bye") 실행
- 스택이 비어있는걸 확인 후 큐에 대기 하고 있는 콜백함수를 다시 스택에 저장
- 콜백함수인 hello 실행
undefined
그렇다면 비동기로 처리한 데이터를 그냥 사용하게 된다면 어떻게 될까?
다음 예제는 비동기 처리 한 데이터를 사용했을때 나타나는 오류이다.
<예제>

<실행 결과>

- 스택에 컨텍스트가 저장됨
- 코드가 순차적으로 실행
- init() 실행
- fetch 비동기 처리하는 함수를 만나 이벤트 루프에 전달 -> 큐에 저장
- 프로미스를 처리하는 .then 메서드를 이벤트 루프에 전달 -> 큐에 저장
- console.log(res.status) 실행
- console.log("hi") 실행
- 코드가 전부 실행되고 스택에 값이 없다면 큐에서 대기하고있던 fetch, .then 함수 스택으로 옮겨져 실행
-> pending 상태의 프로미스의 반환값을 읽으려 했기때문에 undefined 출력
async/await
- 비동기 함수를 다루기 위해 es8부터 등장한 문법
- async 함수는 프로미스를 반환한다.
- async 함수 내부에서만 await 을 사용 할 수 있다.
- await 은 프로미스 앞에 붙어 프로미스의 상태가 fullfilled, rejected 될 때까지 기다린다.
<예제>

<실행 결과>

-> await 을 통해 fetch 비동기 함수가 값 반환시까지 대기하였다가 순차적으로 코드가 실행된다.