await cấp cao nhất cho phép các mô-đun hoạt động như các hàm không đồng bộ, tức là chúng có thể tạm dừng thực thi mô-đun để chờ các lời hứa. Điều này cực kỳ hữu ích cho việc tải có điều kiện các phần phụ thuộc không đồng bộ (như polyfill hoặc thư viện phụ nặng) chỉ khi trình duyệt yêu cầu.
Bằng cách sử dụng await cấp cao nhất, bạn có thể đóng gói logic tải có điều kiện bên trong một mô-đun duy nhất, ngăn chặn hiệu quả các mô-đun người dùng hạ nguồn thực thi cho đến khi phần phụ thuộc được tải đầy đủ và sẵn sàng.
Mẫu polyfill có điều kiện
Mặc dù bạn có thể sử dụng await cấp cao nhất để tải có điều kiện mọi phần phụ thuộc không đồng bộ là một mô-đun, nhưng cách hay để sử dụng mẫu tải phần phụ thuộc có điều kiện là tải có điều kiện polyfill cho các trình duyệt không hỗ trợ một tính năng cụ thể. Phương pháp này đóng gói tính năng phát hiện và nhập động bên trong một mô-đun phần phụ thuộc duy nhất.
Trong trường hợp sau, polyfill thuộc tính popover được tải có điều kiện nếu không có trên 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();
}
Sắp xếp thứ tự nhập mô-đun và tránh lỗi trước Safari 27
BẮT BUỘC: Bạn phải định cấu trúc biểu đồ mô-đun để mô-đun await cấp cao nhất được nhập từ một điểm truy cập duy nhất và hoàn tất trước khi các mô-đun hạ nguồn đánh giá:
- KHÔNG đặt các lệnh nhập tĩnh đồng cấp trong tệp mục nhập (ví dụ:
import './conditionally-load-polyfill.js'; import './app.js';). Theo thông số kỹ thuật đánh giá mô-đun ECMAScript,awaitcấp cao nhất chỉ tạm ngưng mô-đun mẹ nhập mô-đun đó (chứ không phải các lệnh nhập tĩnh đồng cấp). Do đó,./app.jssẽ đánh giá đồng thời trong tất cả trình duyệt trước khi polyfill tải xong. - KHÔNG nhập đồng thời mô-đun
awaitcấp cao nhất từ nhiều mô-đun đồng cấp (ví dụ: cảa.jsvàb.jsđều nhập tĩnh./conditionally-load-polyfill.js). Mặc dù Safari 27 đã khắc phục trình tải mô-đun của WebKit để hỗ trợ việc nhập đồng thời các mô-đunawaitcấp cao nhất theo thông số kỹ thuật, nhưng Safari 15–26.6 không hoạt động khi nhiều mô-đun đồng thời nhập một mô-đun chứaawaitcấp cao nhất (xem khả năng tương thích của trình duyệt MDN).
Thay vào đó, hãy chọn một trong hai mẫu tuỳ thuộc vào cấu trúc mô-đun của bạn:
- Mô-đun điểm truy cập duy nhất (như trong
main.jsở trên): Nếu mô-đun điểm truy cập của bạn chạy trực tiếp logic khởi chạy phụ thuộc, hãy nhập tĩnh./conditionally-load-polyfill.jsở đầu mô-đun đó và chạy mã trong phần nội dung của mô-đun. - Khởi động các mô-đun ứng dụng riêng biệt: Nếu mô-đun mục nhập của bạn uỷ quyền cho các mô-đun ứng dụng hạ nguồn (chẳng hạn như
./app.js), hãy liên kết các lệnh gọiimport()động vớiawaitcấp cao nhất để./app.jschỉ được tìm nạp và đánh giá sau khi mô-đun polyfill phân giải:
// 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');
Chiến lược dự phòng
Mặc dù await cấp cao nhất cơ bản đã được hỗ trợ trên các trình duyệt chính kể từ năm 2021 (Chrome 89, Edge 89, Firefox 89 và Safari 15), nhưng tính năng này chỉ đạt được mức độ tuân thủ đầy đủ thông số kỹ thuật trong Safari 27 (xem khả năng tương thích của trình duyệt MDN).
- Safari 15 – 26.6: Miễn là bạn tuân theo mẫu điểm truy cập duy nhất trong phần trước để nhiều mô-đun đồng cấp không đồng thời nhập mô-đun
awaitcấp cao nhất, bạn có thể yên tâm dựa vàoawaitcấp cao nhất mà không cần dự phòng thêm. - Trình duyệt cũ (trước năm 2021): Nếu ứng dụng của bạn phải hỗ trợ các trình duyệt không hỗ trợ
awaitcấp cao nhất, hãy tránh sử dụngawaitcấp cao nhất và gói hoạt động điều phốiimport()có điều kiện trong một hàmasynctiêu chuẩn hoặc chuỗi hứa hẹn.then().