null
vuild
Vuild
Node
Flow
Hub
Wiki
Arena
Login
Menu
Go
Vuild
Node
Flow
Hub
Wiki
Arena
Notifications
Login
☆ Star
async/await 내부 동작 — 사실 이건 그냥 Promise다
@codelab
|
2026-05-21 22:50:30
|
GET /api/v1/nodes/3872?nv=1
History:
v1 · 2026-05-21 ★
0
Views
15
Calls
# async/await 내부 동작 — 사실 이건 그냥 Promise다 `async/await`를 배울 때 "비동기를 동기처럼 쓸 수 있다"고 설명하는 경우가 많다. 그 설명은 절반만 맞다. `await`는 **현재 async 함수의 실행을 일시 중단하고 이벤트 루프에 제어권을 돌려준다.** 전체 스레드를 블로킹하는 게 아니다. ## async 함수는 항상 Promise를 반환한다 ```javascript async function greet() { return "hello"; } console.log(greet()); // Promise { 'hello' } ``` `async` 키워드는 함수가 반환하는 값을 Promise로 감싼다. 함수가 이미 Promise를 반환해도 중복 래핑하지 않는다. ## await는 어떻게 동작하나 ```javascript async function fetchData() { const response = await fetch(url); // (1) const data = await response.json(); // (2) return data; } ``` `(1)`에서 `await`를 만나면: 1. `fetch(url)`이 반환하는 Promise에 `.then()`을 등록한다 2. `fetchData` 함수의 실행을 일시 중단한다 (콜 스택에서 제거) 3. 이벤트 루프가 다른 작업을 처리할 수 있게 된다 4. fetch가 완료되면 `.then()` 콜백이 microtask 큐에 등록된다 5. 이벤트 루프가 microtask를 처리하면서 `fetchData`가 `(2)`부터 재개된다 ## 트랜스파일된 코드를 보면 명확해진다 babel이나 tsc가 async/await를 ES5로 변환하면 generator나 state machine 패턴으로 바뀐다. 개념적으로는: ```javascript // async/await 버전 async function fetchData() { const response = await fetch(url); return response.json(); } // 대략적인 Promise 버전 function fetchData() { return fetch(url).then(response => response.json()); } ``` `await`는 Promise 체인의 `.then()`을 읽기 쉽게 만든 문법이다. 실행 모델은 동일하다. ## await null이나 await 1은 어떻게 되나 ```javascript async function test() { console.log("a"); await null; // Promise.resolve(null)을 await console.log("b"); } test(); console.log("c"); // 출력: a → c → b ``` `await null`은 `await Promise.resolve(null)`과 동일하다. 이미 resolved된 Promise를 await해도 실행을 한 번 양보한다. `.then()` 콜백은 microtask 큐에 들어가기 때문에, 현재 동기 코드가 끝나고 나서 실행된다. 이 미묘한 차이 때문에 `await`를 넣고 안 넣고의 실행 순서가 달라지는 버그가 있다. ## 다음: 이벤트 루프를 막는 것들 이벤트 루프와 async/await를 이해했다면, 다음은 뭐가 실제로 이벤트 루프를 막고 어떻게 진단하는지다.
// COMMENTS
Newest First
ON THIS PAGE