How to use await outside of an async function in JavaScript?

In JavaScript, the await keyword can only be used inside async functions. However, there are several techniques to work with asynchronous code when you need to use await at the top level or outside of async functions.

Here, we will learn different approaches to handle asynchronous operations outside of regular async functions.

Using Immediately Invoked Function Expression (IIFE)

The most common approach is to wrap your code in an immediately invoked async function expression. This allows you to use await within the function scope.

Syntax

(async () => {
    let result = await fetchData();
    // Use result here
})();

In the above syntax, we create an async arrow function and immediately invoke it using parentheses.

Example 1: Using IIFE with API Call

In this example, we use an IIFE to fetch data from an API using axios. The await keyword waits for the API response before proceeding.

<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.3/axios.min.js"></script>
</head>
<body>
    <h2>Using <i>await</i> with immediately invoking function expression</h2>
    <div id="output"></div>
    
    <script>
        let output = document.getElementById('output');

        (async () => {
            try {
                let result = await axios.get("https://dummyjson.com/products/1");
                
                output.innerHTML += "API Response:<br/>";
                output.innerHTML += `Title: ${result.data.title}<br/>`;
                output.innerHTML += `Price: $${result.data.price}<br/>`;
                output.innerHTML += `Description: ${result.data.description}<br/>`;
            } catch (error) {
                output.innerHTML += "Error: " + error.message;
            }
        })();
    </script>
</body>
</html>

Using Promises with then/catch

Instead of using async/await, you can work directly with promises using .then() and .catch() methods. This approach doesn't require an async function wrapper.

Syntax

promise.then((response) => {
    // Handle successful response
})
.catch((error) => {
    // Handle errors
});

Example 2: Using Promises for API Call

This example demonstrates the same API call using promises instead of async/await syntax.

<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.3/axios.min.js"></script>
</head>
<body>
    <h2>Using <i>promises</i> instead of async-await</h2>
    <div id="output"></div>
    
    <script>
        let output = document.getElementById('output');
        
        axios.get("https://dummyjson.com/products/1")
            .then((result) => {
                output.innerHTML += "API Response using Promises:<br/>";
                output.innerHTML += `Title: ${result.data.title}<br/>`;
                output.innerHTML += `Price: $${result.data.price}<br/>`;
                output.innerHTML += `Category: ${result.data.category}<br/>`;
            })
            .catch((error) => {
                output.innerHTML += "Error: " + error.message;
            });
    </script>
</body>
</html>

Example 3: Creating Custom Promise

This example shows how to create and handle a custom promise that gets rejected.

<html>
<body>
    <h2>Custom Promise Example</h2>
    <div id="output"></div>
    
    <script>
        let output = document.getElementById('output');
        
        let customPromise = new Promise((resolve, reject) => {
            // Simulating an operation that fails
            setTimeout(() => {
                reject("Operation failed after 2 seconds");
            }, 2000);
        });
        
        customPromise
            .then((response) => {
                output.innerHTML += "Success: " + response;
            })
            .catch((error) => {
                output.innerHTML += "Error caught: " + error;
            });
            
        output.innerHTML += "Promise created, waiting for result...<br/>";
    </script>
</body>
</html>

Comparison of Approaches

Approach Pros Cons Best For
IIFE with async/await Clean syntax, error handling with try/catch Extra function wrapper Complex async operations
Promises with then/catch No function wrapper needed Can lead to callback chaining Simple async operations

Top-Level Await (Modern Alternative)

Modern JavaScript environments support top-level await in ES modules, allowing await directly at the module level without wrapping in an async function.

// In an ES module (.mjs file or with "type": "module")
const data = await fetch('/api/data');
const result = await data.json();
console.log(result);

Conclusion

Use IIFE with async/await for complex operations that benefit from try/catch error handling. For simpler cases, promises with then/catch provide a straightforward alternative without function wrapping.

Updated on: 2026-03-15T23:19:00+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements