Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The await operator is used to pause the execution of an asynchronous function until a Promise is settled (either fulfilled or rejected), and to synchronously extract its fulfillment value. It fundamentally acts as syntactic sugar over the Promise.prototype.then() method, allowing asynchronous, promise-based behavior to be written in a synchronous, top-down execution style.

Syntax

const returnValue = await expression;
  • expression: A Promise, a thenable object, or any synchronous value to wait for.
  • returnValue: The fulfilled value of the promise, or the value itself if the expression is not a promise.

Execution Mechanics

When the JavaScript engine encounters an await operator, it performs the following sequence of operations:
  1. Expression Evaluation: The engine evaluates the expression immediately on the right side of the await keyword.
  2. Context Suspension: The engine suspends the execution context of the current async function. It yields control back to the caller of the async function, allowing the caller’s synchronous code to continue executing. Control only returns to the event loop once the synchronous call stack is completely empty.
  3. Microtask Queuing: The engine waits for the evaluated Promise to settle. Once the Promise settles, the engine enqueues a microtask to resume the remainder of the async function (everything following the await operator).
  4. Resumption:
    • On Fulfillment: If the Promise fulfills, the await expression evaluates to the fulfillment value, and the function’s execution resumes.
    • On Rejection: If the Promise rejects, the await expression throws the rejection reason as an exception. This exception propagates synchronously and can be intercepted using a standard try...catch block.

Evaluation Rules

The behavior of await changes depending on the type of the evaluated expression:
async function evaluationMechanics() {
    // 1. Standard Promise: Pauses until fulfillment, returns the value.
    const resolvedValue = await Promise.resolve("Success"); 
    
    // 2. Rejected Promise: Throws the rejection reason.
    try {
        await Promise.reject(new Error("Failure"));
    } catch (err) {
        // err captures the rejection reason
    }

    // 3. Non-Promise (Primitive/Object): Implicitly wrapped via Promise.resolve().
    // Execution is still suspended and resumption is pushed to the microtask queue.
    const primitive = await 42; // Evaluates to 42

    // 4. Thenables: Awaits objects implementing a custom `then()` method 
    // (Promises/A+ compliance).
    const thenable = {
        then: function(resolve, reject) {
            resolve("Resolved from thenable");
        }
    };
    const customResult = await thenable; 
}

Scope Restrictions

Historically, the await operator could only be used within the body of a function declared with the async keyword. Attempting to use await in a standard synchronous function results in a SyntaxError. With the introduction of ECMAScript 2022, Top-Level Await is supported. This allows the await operator to be used outside of async functions, provided it is at the top level of an ECMAScript Module (.mjs or <script type="module">). Because ES modules are evaluated bottom-up (post-order traversal), child modules (dependencies) are evaluated before the module that imports them. When used at the top level, await halts the evaluation of the current module and prevents parent modules (importers) from evaluating until the Promise settles.
// Valid only at the top level of an ES Module
const moduleDependency = await import('./dynamic-module.js');
export const initializedData = await moduleDependency.initialize();
Master JavaScript with Deep Grasping Methodology!Learn More