Problem Statement
Can you use await outside an async function?
Explanation
Await can be used at the top level in ES modules, introduced in ES2022.
Traditionally, await could only be used inside async functions.
Top-level await allows modules to act like async functions. Useful for dynamic imports and async initialization.
Other modules importing this module will wait for the await to complete.
In regular scripts or inside functions, await still requires async.
Top-level await simplifies module initialization but should be used carefully as it blocks module loading.
Code Solution
SolutionRead Only
// TOP-LEVEL AWAIT (ES2022 modules)
// module.js
const data = await fetch('/api/data').then(r => r.json());
export default data;
// Other modules importing this wait for fetch to complete
// Traditional way (still needed in non-modules)
(async () => {
const data = await fetch('/api/data');
console.log(data);
})();
// ASYNC FUNCTION REQUIRED
async function fetchData() {
const response = await fetch('/api/data');
const data = await response.json();
return data;
}
// Error: await without async
function wrong() {
// const data = await fetch('/api'); // SyntaxError!
}
// PRACTICAL EXAMPLES
// Sequential awaits
async function sequential() {
const user = await fetchUser(); // Wait
const posts = await fetchPosts(); // Then wait
const comments = await fetchComments(); // Then wait
return {user, posts, comments};
}
// Total time: time1 + time2 + time3
// Parallel awaits
async function parallel() {
const [user, posts, comments] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchComments()
]);
return {user, posts, comments};
}
// Total time: max(time1, time2, time3)
// Error handling
async function withErrorHandling() {
try {
const data = await fetch('/api/data');
return data.json();
} catch (error) {
console.error('Error:', error);
return null;
}
}
// Multiple try-catch blocks
async function multipleTryCatch() {
try {
const user = await fetchUser();
} catch (error) {
console.error('User fetch failed');
}
try {
const posts = await fetchPosts();
} catch (error) {
console.error('Posts fetch failed');
}
}
// Await in loops
async function processItems(items) {
// Sequential processing
for (const item of items) {
await processItem(item); // Wait for each
}
// Parallel processing
await Promise.all(items.map(item => processItem(item)));
}
// Conditional await
async function conditionalAwait(useCache) {
if (useCache) {
return getCachedData();
} else {
return await fetchFreshData(); // Only await if needed
}
}
// TOP-LEVEL AWAIT USE CASES
// Dynamic imports
const module = await import('./module.js');
// Database connection
const db = await connectDatabase();
// Feature detection
const isSupported = await checkFeatureSupport();
// Config loading
const config = await fetch('/config.json').then(r => r.json());
// Resource initialization
const resources = await loadResources();