If you've written asynchronous JavaScript in the last few years, you're probably familiar with async functions and the await keyword. You define an async function, then you use the await keyword to wait for asynchronous values to resolve. This lets you write asynchronous code in a way that feels more synchronous:

const API = "https://jsonplaceholder.typicode.com/users";

async function main() {
try {
const response = await fetch(API);
const users = await getJSON(response);
console.log(users);
} catch (error) {
console.error(error);
}
}

async function getJSON(response) {
if (response.ok) {
const data = await response.json();
return Promise.resolve(data);
}

const { status, statusText } = response;
const error = new Error(`${status} ${statusText}`);

return Promise.reject(error);
}

main();

Until recently (Chrome 89, Firefox 89, Safari 15), you could only use the await keyword inside an async function. Now, inside ES modules, you can use the await keyword at the top level. More from the MDN Web Docs:

You can use the await keyword on its own (outside of an async function) within a JavaScript module. This means modules, with child modules that use await, wait for the child module to execute before they themselves run. All while not blocking other child modules from loading.

In the following example, we fetch the API data and export it from the module. Notice that in the try...catch block, we use the await keyword at the top level, i.e. outside an async function:

const API = "https://jsonplaceholder.typicode.com/users";

let users;

async function getJSON(response) {
if (response.ok) {
const data = await response.json();
return Promise.resolve(data);
}

const { status, statusText } = response;
const error = new Error(`${status} ${statusText}`);

return Promise.reject(error);
}

try {
const response = await fetch(API);
users = await getJSON(response);
} catch (error) {
users = error;
}

export default users;

This means we can just import the resolved data inside another module. How cool is that!?

import users from "./users.js";

if (users instanceof Error) {
console.error(users);
} else {
console.log(users);
}

For your convenience, here's the code from this blog post.

Further reading