Koşullu Eşzamansız Bağımlılıklar

Web özellikleri: Üst düzey await

Üst düzey await, modüllerin eşzamansız işlevler olarak çalışmasına olanak tanır. Yani modüller, promise'leri beklemek için modül yürütmeyi duraklatabilir. Bu, polyfill'ler veya ağır ikincil kitaplıklar gibi eşzamansız bağımlılıkları yalnızca tarayıcı tarafından gerektiğinde koşullu olarak yüklemek için son derece kullanışlıdır.

Üst düzey await kullanarak koşullu yükleme mantığını tek bir modülde kapsayabilir ve bağımlılık tamamen yüklenip hazır olana kadar alt tüketici modüllerinin yürütülmesini etkili bir şekilde engelleyebilirsiniz.

Koşullu polyfill kalıbı

Üst düzey await, modül olan tüm eş zamansız bağımlılıkları koşullu olarak yüklemek için kullanılabilir. Koşullu bağımlılık yükleme kalıbının iyi bir kullanım şekli, belirli bir özelliği desteklemeyen tarayıcılar için polyfill'leri koşullu olarak yüklemektir. Bu yaklaşım, özellik algılamayı ve dinamik içe aktarmayı tek bir bağımlılık modülünde birleştirir.

Aşağıdaki örnekte, popover özelliği polyfill'i HTMLElement.prototype üzerinde mevcut değilse koşullu olarak yüklenir:

// 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();
}

Modül içe aktarma işlemlerini sıralama ve Safari 27 öncesi hatayı önleme

ZORUNLU: Modül grafiğinizi, üst düzey await modülü tek bir giriş noktasından içe aktarılacak ve alt modüller değerlendirilmeden önce tamamlanacak şekilde yapılandırmanız gerekir:

  • Kardeş statik içe aktarmaları bir giriş dosyasına YERLEŞTİRMEYİN (ör. import './conditionally-load-polyfill.js'; import './app.js';). ECMAScript modül değerlendirme spesifikasyonuna göre, üst düzey await yalnızca kendisini içe aktaran üst modülü askıya alır (kardeş statik içe aktarmaları değil). Bu nedenle ./app.js, polyfill yüklenmeden önce tüm tarayıcılarda eşzamanlı olarak değerlendirilir.
  • Üst düzey await modülünü birden fazla kardeş modülden aynı anda İÇE AKTARMAYIN (örneğin, hem a.js hem de b.js'nin ./conditionally-load-polyfill.js'i statik olarak içe aktarması). Safari 27, WebKit'in modül yükleyicisini üst düzey await modüllerinin eşzamanlı içe aktarma işlemlerini destekleyecek şekilde düzeltmiş olsa da Safari 15-26.6, birden fazla modülün üst düzey await içeren bir modülü aynı anda içe aktarması durumunda başarısız olur (MDN tarayıcı uyumluluğu bölümüne bakın).

Bunun yerine, modül yapınıza bağlı olarak iki kalıptan birini seçin:

  1. Tek giriş modülü (yukarıda main.js ile gösterilmiştir): Giriş modülünüz bağımlı başlatma mantığını doğrudan çalıştırıyorsa ./conditionally-load-polyfill.js öğesini bu modülün en üstüne statik olarak içe aktarın ve kodunuzu gövdesinde çalıştırın.
  2. Ayrı uygulama modüllerini önyükleme: Giriş modülünüz, alt uygulama modüllerine (ör. ./app.js) yetki veriyorsa dinamik import() çağrılarını üst düzey await ile zincirleyin. Böylece ./app.js yalnızca polyfill modülü çözümlendikten sonra getirilir ve değerlendirilir:
// 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');

Yedek stratejiler

Temel üst düzey await, 2021'den beri başlıca tarayıcılarda (Chrome 89, Edge 89, Firefox 89 ve Safari 15) destekleniyor olsa da spesifikasyonun tamamına uygunluk yalnızca Safari 27'de sağlandı (MDN tarayıcı uyumluluğu bölümüne bakın).

  • Safari 15-26.6: Önceki bölümde yer alan tek giriş noktası kalıbını uyguladığınız sürece birden fazla kardeş modül, üst düzey await modülünü aynı anda içe aktarmaz. Bu durumda, ek bir yedek olmadan üst düzey await modülünü güvenle kullanabilirsiniz.
  • Eski tarayıcılar (2021 öncesi): Uygulamanızın üst düzey await desteği olmayan tarayıcıları desteklemesi gerekiyorsa üst düzey await kullanmaktan kaçının ve koşullu import() düzenlemenizi standart bir async işlevi veya .then() Promise zinciriyle sarmalayın.