최상위 await를 사용하면 모듈이 비동기 함수로 작동할 수 있습니다. 즉, 모듈 실행을 일시중지하여 프로미스를 기다릴 수 있습니다. 이는 브라우저에서 필요할 때만 비동기 종속 항목(예: 폴리필 또는 무거운 보조 라이브러리)을 조건부로 로드하는 데 매우 유용합니다.
최상위 await를 활용하면 조건부 로드 로직을 단일 모듈 내에 캡슐화하여 종속 항목이 완전히 로드되고 준비될 때까지 다운스트림 소비자 모듈이 실행되지 않도록 효과적으로 방지할 수 있습니다.
조건부 polyfill 패턴
최상위 await를 사용하여 모듈인 비동기 종속 항목을 조건부로 로드할 수 있지만, 조건부 종속 항목 로드 패턴을 사용하면 특정 기능을 지원하지 않는 브라우저의 폴리필을 조건부로 로드할 수 있습니다. 이 접근 방식은 단일 종속 항목 모듈 내에서 기능 감지와 동적 가져오기를 캡슐화합니다.
다음 경우에 popover 속성 폴리필은 HTMLElement.prototype에 없으면 조건부로 로드됩니다.
// conditionally-load-polyfill.js
// Check if the feature is missing before doing work.
// MANDATORY: Prefer checking HTMLElement.prototype over window or document
// when checking for a global DOM attribute or property like popover.
if (!('popover' in HTMLElement.prototype)) {
// Use top-level await to pause the execution of any module that imports this file
// until the polyfill finishes downloading and executing.
await import('/path/to/popover-polyfill.js');
}
// Export a marker if needed by your application
export const polyfillLoaded = true;
// main.js
// MANDATORY: Because conditionally-load-polyfill.js uses top-level await,
// this import will block execution of main.js until the polyfill is ready.
import './conditionally-load-polyfill.js';
// Now it is safe to use the feature (e.g., showing a popover)
const myPopover = document.getElementById('my-popover');
if (myPopover) {
myPopover.showPopover();
}
모듈 가져오기 시퀀싱 및 Safari 27 이전 버그 방지
필수: 최상위 await 모듈을 단일 진입점에서 가져오고 다운스트림 모듈이 평가되기 전에 완료되도록 모듈 그래프를 구성해야 합니다.
- 항목 파일에 동위 정적 가져오기를 배치하지 마세요 (예:
import './conditionally-load-polyfill.js'; import './app.js';). ECMAScript 모듈 평가 사양에 따라 최상위 수준await는 동위 정적 가져오기가 아닌 이를 가져오는 상위 모듈만 정지하므로 폴리필 로드가 완료되기 전에 모든 브라우저에서./app.js가 동시에 평가됩니다. - 여러 동위 모듈에서 최상위 수준
await모듈을 동시에 가져오지 마세요 (예:a.js및b.js가 모두./conditionally-load-polyfill.js를 정적으로 가져오는 경우). Safari 27은 사양에 따라 최상위 수준await모듈의 동시 가져오기를 지원하도록 WebKit의 모듈 로더를 수정했지만, Safari 15~26.6은 여러 모듈이 최상위 수준await가 포함된 모듈을 동시에 가져올 때 실패합니다(MDN 브라우저 호환성 참고).
대신 모듈 구조에 따라 다음 두 가지 패턴 중 하나를 선택합니다.
- 단일 항목 모듈 (위의
main.js에 표시됨): 항목 모듈이 종속 초기화 로직을 직접 실행하는 경우 해당 모듈 상단에서./conditionally-load-polyfill.js를 정적으로 가져오고 본문에서 코드를 실행합니다. - 별도의 애플리케이션 모듈 부트스트랩: 항목 모듈이 다운스트림 애플리케이션 모듈 (예:
./app.js)에 위임하는 경우 최상위await를 사용하여 동적import()호출을 연결하여 폴리필 모듈이 확인된 후에만./app.js를 가져오고 평가합니다.
// main.js
// MANDATORY: Chain dynamic imports with top-level await when bootstrapping separate
// application modules so './app.js' waits for the polyfill to finish loading.
// DO NOT use sibling static imports (`import './conditionally-load-polyfill.js'; import './app.js';`),
// which evaluate concurrently and execute './app.js' before the polyfill is ready.
await import('./conditionally-load-polyfill.js');
await import('./app.js');
대체 전략
기본 최상위 await는 2021년부터 주요 브라우저 (Chrome 89, Edge 89, Firefox 89, Safari 15)에서 지원되었지만 Safari 27에서만 전체 사양을 준수했습니다(MDN 브라우저 호환성 참고).
- Safari 15~26.6: 여러 동위 모듈이 최상위
await모듈을 동시에 가져오지 않도록 이전 섹션의 단일 진입점 패턴을 따르는 한 추가 대체 없이 최상위await를 안전하게 사용할 수 있습니다. - 기존 브라우저 (2021년 이전): 애플리케이션이 최상위 수준
await지원이 없는 브라우저를 지원해야 하는 경우 최상위 수준await를 피하고 조건부import()조정을 표준async함수 또는.then()프로미스 체인으로 래핑합니다.