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.

An async function is a function declared with the async keyword that enables asynchronous, Promise-based behavior to be written in a synchronous style. It operates as syntactic sugar over JavaScript’s native Promises, allowing the use of the await operator to suspend the function’s execution context until a Promise settles, without blocking the main thread.

Syntax Variations

The async modifier can be applied to various function declarations and expressions:
// Function Declaration
async function process() {}

// Function Expression
const process = async function() {};

// Arrow Function
const process = async () => {};

// Object Method
const obj = {
  async process() {}
};

// Class Method
class Processor {
  async process() {}
}

Return Value Mechanics

An async function always returns a newly allocated Promise object, regardless of the explicit return statement within the function body. The JavaScript engine intercepts the return value and applies the following rules:
  • Explicit Non-Promise Return: The value is implicitly wrapped in a resolved Promise (equivalent to Promise.resolve(value)).
  • Explicit Promise Return: The function returns a new Promise that resolves to (adopts the state of) the returned Promise. It does not return the exact same Promise object reference.
  • Thrown Exception: The error is implicitly wrapped in a rejected Promise (equivalent to Promise.reject(error)).
async function returnString() {
  return "resolved"; // Returns a new Promise resolving to "resolved"
}

const p = Promise.resolve("inner promise");
async function returnPromise() {
  return p; // Returns a NEW Promise that adopts the state of 'p' (returnPromise() !== p)
}

async function throwError() {
  throw new Error("failed"); // Returns a new Promise rejecting with the Error
}

The await Operator

The await expression is exclusively valid within async functions (and top-level modules). It unwraps a Promise, extracting its fulfillment value. If the expression evaluated by await is a non-Promise value, the JavaScript engine implicitly converts it into a resolved Promise (equivalent to Promise.resolve(value)). When the JavaScript engine encounters an await expression, it performs the following sequence:
  1. Evaluates the expression on the right side of await.
  2. Suspends the execution of the async function.
  3. Yields control back to the calling context, allowing the event loop to continue processing other tasks.
  4. Resumes the function’s execution in the microtask queue once the awaited Promise settles (resolves or rejects).
If the awaited Promise rejects, the await expression throws the rejection reason as an exception. This allows asynchronous errors to be handled using standard synchronous try...catch blocks.
async function handleValues(promise) {
  try {
    // Execution pauses here until 'promise' settles
    const result = await promise; 
    
    // Non-Promise values are implicitly converted to resolved Promises
    const immediateResult = await 42; // Equivalent to await Promise.resolve(42)
    
    return result + immediateResult;
  } catch (error) {
    // Catches rejection if 'promise' rejects
    console.error(error);
  }
}

Execution Flow and the Event Loop

Invoking an async function executes its body synchronously up to the first await expression. The suspension of the function only occurs after the expression to the right of the await is evaluated. If an async function contains no await expressions, it executes entirely synchronously, though its return value remains wrapped in a newly allocated Promise.
async function executionOrder() {
  console.log("2. Inside async function, before await");
  
  await Promise.resolve(); // Execution suspended, control yielded
  
  console.log("4. Inside async function, after await (Microtask)");
}

console.log("1. Before calling async function");
executionOrder();
console.log("3. After calling async function");

// Console Output:
// 1. Before calling async function
// 2. Inside async function, before await
// 3. After calling async function
// 4. Inside async function, after await (Microtask)
Master JavaScript with Deep Grasping Methodology!Learn More