All Articles

Top-level await

Top-level await enables developers to use the await keyword outside of async functions. It acts like a big async function causing other modules who import them to wait before they start evaluating their body.

The old behavior

When async/await was first introduced, attempting to use an await outside of an async function resulted in a SyntaxError.

await Promise.resolve(console.log('🎉'))
// → SyntaxError: await is only valid in async function

Many developers utilized immediately-invoked async function expressions as a way to get access to the feature.

(async function() {
  await Promise.resolve(console.log('🎉'))
  // → 🎉
})()

Or also declare an async function and then call it:

const doSomething = async () => {
  await Promise.resolve(console.log('🎉'))
  // → 🎉
}

doSomething()

The new behavior

With top-level await, the above code instead works the way you’d expect within modules:

await Promise.resolve(console.log('🎉'))
// → 🎉

Note: Top-level await only works at the top level of modules. There is no support for classic scripts or non-async functions.

Top level await

Use cases

Dynamic dependency pathing

const strings = await import(`/i18n/${navigator.language}`)

This allows for modules to use runtime values in order to determine dependencies. This is useful for things like development/production splits, internationalization, environment splits, etc.

Resource initialization

const connection = await dbConnector()

This allows modules to represent resources and also to produce errors in cases where the module cannot be used.

Dependency fallbacks

The following example attempts to load a JavaScript library from CDN A, falling back to CDN B if that fails:

let jQuery
try {
  jQuery = await import('https://cdn-a.example.com/jQuery')
} catch {
  jQuery = await import('https://cdn-b.example.com/jQuery')
}
Published 23 Aug 2020

Recent Posts

Super Expressive - Easy Peasy Regex Generating

Struggling to write regex from scratch, checkout super-expressive, and a playground written by my friend @nartc

A childhood memory Tetris game built with Angular 10 and Akita

I made a retro Tetris game with Angular. The first game that I have ever built :)


Follow @tuantrungvo on Twitter for more!