await ระดับบนสุดช่วยให้โมดูลทำหน้าที่เป็นฟังก์ชันแบบอะซิงโครนัสได้ ซึ่งหมายความว่าโมดูลสามารถหยุดการดำเนินการชั่วคราวเพื่อรอ Promise วิธีนี้มีประโยชน์อย่างยิ่งสำหรับการโหลดทรัพยากร Dependency แบบไม่พร้อมกันตามเงื่อนไข เช่น Polyfill หรือไลบรารีรองที่มีขนาดใหญ่ เฉพาะเมื่อเบราว์เซอร์ต้องการเท่านั้น
การใช้ await ระดับบนสุดจะช่วยให้คุณรวมตรรกะการโหลดแบบมีเงื่อนไขไว้ภายในโมดูลเดียวได้ ซึ่งจะป้องกันไม่ให้โมดูลผู้บริโภคปลายน้ำทำงานจนกว่าจะโหลดทรัพยากร Dependency จนเสร็จสมบูรณ์และพร้อมใช้งาน
รูปแบบ Polyfill แบบมีเงื่อนไข
แม้ว่า await ระดับบนสุดจะใช้เพื่อโหลดทรัพยากร Dependency แบบไม่พร้อมกันที่เป็นโมดูลตามเงื่อนไขได้ แต่การใช้รูปแบบการโหลดทรัพยากร Dependency ตามเงื่อนไขที่ดีคือการโหลด Polyfill ตามเงื่อนไขสำหรับเบราว์เซอร์ที่ไม่รองรับฟีเจอร์ที่เฉพาะเจาะจง แนวทางนี้จะรวมการตรวจหาฟีเจอร์และการนําเข้าแบบไดนามิกไว้ในโมดูลทรัพยากร Dependency เดียว
ในกรณีต่อไปนี้ ระบบจะโหลด Polyfill ของแอตทริบิวต์ 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';) ตามข้อกําหนดการประเมินโมดูล ECMAScriptawaitระดับบนสุดจะระงับเฉพาะโมดูลหลักที่นําเข้าเท่านั้น ไม่ใช่การนําเข้าแบบคงที่ระดับเดียวกัน ดังนั้น./app.jsจะประเมินพร้อมกันในเบราว์เซอร์ทั้งหมดก่อนที่ Polyfill จะโหลดเสร็จ - อย่าใช้โมดูล
awaitระดับบนสุดจากโมดูลพี่น้องหลายรายการพร้อมกัน (เช่น มีทั้งa.jsและb.jsนำเข้า./conditionally-load-polyfill.jsแบบคงที่) แม้ว่า Safari 27 จะแก้ไขตัวโหลดโมดูลของ WebKit เพื่อรองรับการนำเข้าโมดูลawaitระดับบนสุดพร้อมกันตามข้อกำหนด แต่ Safari 15-26.6 จะทำงานไม่สำเร็จเมื่อโมดูลหลายรายการนำเข้าโมดูลที่มีawaitระดับบนสุดพร้อมกัน (ดูความเข้ากันได้ของเบราว์เซอร์ MDN)
แต่ให้เลือกรูปแบบใดรูปแบบหนึ่งจาก 2 รูปแบบต่อไปนี้ โดยขึ้นอยู่กับโครงสร้างโมดูลของคุณ
- โมดูลรายการเดียว (แสดงใน
main.jsด้านบน): หากโมดูลรายการเรียกใช้ตรรกะการเริ่มต้นที่ขึ้นต่อกันโดยตรง ให้ใช้การนำเข้าแบบคงที่./conditionally-load-polyfill.jsที่ด้านบนของโมดูลนั้นและเรียกใช้โค้ดในเนื้อหา - การบูตสแตรปโมดูลแอปพลิเคชันแยกต่างหาก: หากโมดูลรายการมอบสิทธิ์ให้โมดูลแอปพลิเคชันปลายทาง (เช่น
./app.js) ให้เชื่อมโยงการเรียกimport()แบบไดนามิกกับawaitระดับบนสุด เพื่อให้ระบบดึงข้อมูลและประเมิน./app.jsหลังจากที่โมดูล Polyfill แก้ไขแล้วเท่านั้น
// 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()