eatthefrog
모던 자바스크립트 모듈 Top-Level await (ES2022) 본문
Top-Level Await은 자바스크립트에서 ES2022(ES13)부터 도입된 기능으로, 모듈의 최상위 레벨에서 await를 사용할 수 있도록 허용합니다. 최상위 레벨에서 비동기 작업을 기다릴 수 있게 되어 코드가 더 간단하고 직관적입니다.

1. Top-Level Await이란?
- 기존에는 await를 함수 내부(특히 async 함수 내)에서만 사용할 수 있었습니다.
- Top-Level Await은 코딩 과정의 취상위에서 "기다려야하는 일을 기다렸다가" 다음으로 넘어가는 것을 의미한다. 즉, 기다려야 하는 일이 끝날때까지 코드 전체를 멈춥니다.
예시
//일반 스크립트
function boilWater() {
return new Promise(resolve => setTimeout(() => resolve("물이 끓었어요!"), 2000));
}
(async () => {
const water = await boilWater(); // `async` 함수 내부에서만 기다림
console.log(water); // 출력: 물이 끓었어요!
})();
// 모듈 방식 : 최상위 레벨에서 await 사용
const boilWater = () => new Promise(resolve => setTimeout(() => resolve("물이 끓었어요!"), 2000));
const water = await boilWater(); // 최상위에서 기다림
console.log(water); // 출력: 물이 끓었어요!
2. 스크립트와 모듈의 차이점
2.1 스크립트 (Script)
일반 스크립트 파일(.js)에서는 최상위 레벨에서 await를 사용할 수 없습니다. 이는 await가 비동기 컨텍스트에서만 작동하기 때문입니다.
예시
// script.js
const result = await Promise.resolve("Hello");
// SyntaxError: Unexpected reserved word
- 이유: 일반 스크립트는 비동기 컨텍스트에서 실행되지 않습니다.
- 해결 방법: 일반 스크립트에서 await를 사용하려면 async 함수 내부에서 사용해야 합니다.
// script.js
(async () => {
const result = await Promise.resolve("Hello");
console.log(result); // 출력: Hello
})();
2.2 모듈 (Module)
ECMAScript 모듈(type="module")에서는 최상위 레벨에서 await를 사용할 수 있습니다. 이는 모듈이 비동기적으로 실행되기 때문입니다.
예시
// 레스토랑 요리 (모듈)
const boilingWater = await boilWater(); // 물이 끓을 때까지 기다림
console.log(boilingWater); // "물이 끓었어요!"
- 이유: 모듈은 항상 비동기 컨텍스트에서 실행되므로 await를 사용할 수 있습니다.
3. Top-Level Await의 작동 방식
3.1 모듈 로딩 지연
Top-Level Await이 사용된 모듈은 해당 비동기 작업이 완료될 때까지 다른 의존 모듈의 실행을 차단합니다.
예시
// a.mjs
export const data = await fetch("https://jsonplaceholder.typicode.com/posts").then(res => res.json());
console.log("a.mjs 완료");
// b.mjs
import { data } from "./a.mjs";
console.log("b.mjs 완료", data);
출력 결과:
a.mjs 완료
b.mjs 완료 [...data]
b.mjs는 a.mjs의 await 작업이 완료된 후 실행됩니다.
3.2 의존성 간 대기
Top-Level Await이 의존성 모듈에 영향을 미칠 수 있습니다. 여러 모듈이 연결된 경우, 모든 비동기 작업이 체인처럼 순서대로 처리됩니다.
4. Top-Level Await의 주요 사용 사례
- 데이터 초기화
- config.mjs export const config = await fetch("/config.json").then(res => res.json());
- 앱이 시작되기 전에 필요한 데이터를 가져와, 다른 코드에서 안전하게 사용할 수 있도록 한다.
- Top-Level Await을 사용하면 데이터를 가져오는 작업을 동기적으로 기다렸다가, 준비된 데이터를 내보내도록 보장할 수 있어요.
- 동적 데이터 로드
- const module = await import("./dynamicModule.mjs");
- 동적 모듈 로드(import())는 본질적으로 비동기 작업이다. 모듈을 가져오는 작업은 네트워크 요청이나 파일 읽기 등 시간이 걸릴 수 있는 작업을 포함한다. Top-Level Await이 없었다면, 동적 로드 작업을 최상위에서 바로 처리할 수 없고, 비동기 함수 안에서 처리해야 했어야 한다.
- top-level await없는 비동기 함수에서 동적 모듈 로드하기
- // dynamicLoader.js
const loadModule = async () => {
const module = await import('./someModule.js');
module.doSomething();
};
loadModule();
- Top-await을 사용하면 코드 실행을 중단하지 않고 필요한 모듈을 로드하고 작업을 이어갈 수 있다.
- 테스트 및 디버깅
- console.log(await Promise.resolve("Testing Top-Level Await"));
- 비동기 작업의 결과를 쉽게 확인할 수 있다.
- Top-Level Await을 사용하면 간단히 테스트하고 결과를 출력할 수 있다.
5. 스크립트와 모듈 사용 요약
특징 스크립트 (Script) 모듈 (Module)
| 최상위 await 사용 | 지원하지 않음 | 지원 |
| 실행 컨텍스트 | 동기적으로 실행 | 비동기적으로 실행 |
| 사용 방법 | async 함수 내에서만 가능 | 최상위 레벨에서 바로 사용 가능 |
| 모듈 의존성 | 의존 모듈과 독립적으로 실행 | Top-Level Await 사용 시 의존성 차단 가능 |
'프론트엔드 노트' 카테고리의 다른 글
| 모던 자바스크립트 ) 함수 생성 방식 3가지 (0) | 2025.01.07 |
|---|---|
| 모던 자바스크립트_Module Pattern(import,export) (1) | 2025.01.02 |
| CSS) 자식박스를 가운데 정렬시키기 위해서 부모 박스에 flex box 설정하는 이유 (1) | 2025.01.01 |
| 모던 자바스크립트_ES6 모듈 VS 스크립트 2탄(파일로딩,다운로드) (1) | 2024.12.31 |
| 모던 자바스크립트 모듈 (0) | 2024.12.31 |