예제 코드
console.log('1. 스크립트 시작');
async function asyncFunction() {
console.log('2. async 함수 시작');
await Promise.resolve('3. Promise 해결');
console.log('4. await 이후 코드');
}
setTimeout(() => console.log('5. setTimeout 콜백'), 0);
asyncFunction();
Promise.resolve('6. 즉시 해결된 Promise').then(console.log);
console.log('7. 스크립트 끝');
이 코드의 실행 순서와 각 부분의 동작을 설명하겠습니다:
콜 스택에 전역 실행 컨텍스트가 추가됩니다.
console.log('1. 스크립트 시작')이 실행되어 출력됩니다.
asyncFunction이 정의됩니다.
setTimeout이 실행되고, 그 콜백은 태스크 큐에 추가됩니다.
asyncFunction()이 호출되어 콜 스택에 추가됩니다.
console.log('2. async 함수 시작')이 실행됩니다.await Promise.resolve('3. Promise 해결')을 만나면, Promise가 즉시 해결되지만 await 이후의 코드는 마이크로태스크 큐에 추가됩니다.asyncFunction은 일시 중단되고 콜 스택에서 제거됩니다.Promise.resolve('6. 즉시 해결된 Promise').then(console.log)가 실행되고, 이 Promise의 then 핸들러가 마이크로태스크 큐에 추가됩니다.
console.log('7. 스크립트 끝')이 실행됩니다.
전역 실행 컨텍스트가 콜 스택에서 제거됩니다.
이벤트 루프가 마이크로태스크 큐를 확인합니다:
이벤트 루프가 태스크 큐를 확인합니다:
따라서 최종 출력 순서는 다음과 같습니다:
1. 스크립트 시작
2. async 함수 시작
7. 스크립트 끝
6. 즉시 해결된 Promise
4. await 이후 코드
5. setTimeout 콜백
이 예제는 async/await, Promise, setTimeout이 어떻게 마이크로태스크 큐, 태스크 큐, 콜 스택과 상호작용하는지 보여줍니다. async 함수 내의 await 이후 코드는 마이크로태스크 큐에 추가되어 일반 Promise then 핸들러와 같은 우선순위로 처리되며, 이들은 모두 setTimeout과 같은 매크로태스크보다 먼저 실행됩니다.
Citations:
[1] https://wikidocs.net/251952
[2] https://yong-nyong.tistory.com/71
[3] https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC-async-await
[4] https://develogger.kro.kr/blog/LKHcoding/148
[5] https://sangminem.tistory.com/479
[6] https://ko.javascript.info/async-await
참조하면 좋은 사이트
[1] https://gruuuuu.github.io/javascript/async-js/
[2] https://velog.io/@kimtaeeeny/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-FE-study16-elk65x5mew
[3] https://nayoungkim00.tistory.com/43
[4] https://ingg.dev/js-work/
[5] https://velog.io/@tykim1227/JS-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC-EventLoop
[6] https://koreanddinghwan.github.io/javascript/asynceawait/
[7] https://perfectacle.github.io/2017/04/03/js-async-function/