Learning Objectives

  • Understand what async/await is
  • Learn the async keyword
  • Master the await keyword
  • Convert Promises to async/await syntax

What is Async/Await?

Async/await is syntactic sugar over Promises that makes asynchronous code look and behave like synchronous code.

Before (Promises):

fetchUser(1)
  .then(user => fetchPosts(user.id))
  .then(posts => console.log(posts))
  .catch(error => console.error(error));

After (Async/Await):

async function getPosts() {
  try {
    const user = await fetchUser(1);
    const posts = await fetchPosts(user.id);
    console.log(posts);
  } catch (error) {
    console.error(error);
  }
}

Benefits:

The async Keyword

The async keyword makes a function return a Promise:

async function myFunction() {
  return 'Hello';
}

// Equivalent to:
function myFunction() {
  return Promise.resolve('Hello');
}

myFunction().then(value => console.log(value)); // 'Hello'

Key Points:

1. Always returns a Promise

async function getValue() {
  return 42;
}

console.log(getValue()); // Promise { 42 }

2. Can use await inside

async function fetchData() {
  const data = await fetch('/api/data');
  return data;
}

3. Works with all function types

// Function declaration
async function func1() {}

// Function expression
const func2 = async function() {};

// Arrow function
const func3 = async () => {};

// Method
const obj = {
  async method() {}
};

The await Keyword

The await keyword pauses execution until a Promise settles:

async function example() {
  console.log('Before await');
  
  const result = await Promise.resolve('value');
  
  console.log('After await');
  console.log(result); // 'value'
}

Rules for await:

1. Only works inside async functions

// ❌ Error: await outside async function
const result = await fetchData();

// ✅ Correct
async function getData() {
  const result = await fetchData();
}

2. Pauses execution, but doesn't block

async function demo() {
  console.log('1');
  await delay(1000);
  console.log('2'); // Runs after 1 second
}

demo();
console.log('3'); // Runs immediately

// Output: 1, 3, 2

Converting Promises to Async/Await

Example 1: Simple Chain

Before:

function getUser() {
  return fetchUser(1)
    .then(user => {
      console.log('User:', user);
      return user;
    });
}

After:

async function getUser() {
  const user = await fetchUser(1);
  console.log('User:', user);
  return user;
}

Example 2: Multiple Steps

Before:

function processOrder(orderId) {
  return fetchOrder(orderId)
    .then(order => validateOrder(order))
    .then(validOrder => processPayment(validOrder))
    .then(payment => sendConfirmation(payment));
}

After:

async function processOrder(orderId) {
  const order = await fetchOrder(orderId);
  const validOrder = await validateOrder(order);
  const payment = await processPayment(validOrder);
  const confirmation = await sendConfirmation(payment);
  return confirmation;
}

Example 3: With Error Handling

Before:

function getData() {
  return fetchData()
    .then(data => processData(data))
    .catch(error => {
      console.error('Error:', error);
      throw error;
    });
}

After:

async function getData() {
  try {
    const data = await fetchData();
    return await processData(data);
  } catch (error) {
    console.error('Error:', error);
    throw error;
  }
}

Real-World Example: Fetching User Profile

async function getUserProfile(userId) {
  const user = await fetch(`/api/users/${userId}`).then(r => r.json());
  const posts = await fetch(`/api/users/${userId}/posts`).then(r => r.json());
  
  return {
    user,
    posts,
    postCount: posts.length
  };
}

getUserProfile(1)
  .then(profile => console.log(profile))
  .catch(error => console.error(error));

Async/Await vs Promises

Feature Promises Async/Await
Syntax .then() chains await keyword
Readability Can get nested Linear, like sync code
Error Handling .catch() try/catch
Debugging Harder Easier
Compatibility ES6 (2015) ES8 (2017)

Important Notes

1. Async Functions Are Non-Blocking

async function slowFunction() {
  await delay(3000);
  console.log('Done');
}

slowFunction(); // Doesn't block
console.log('This runs immediately');

2. Async/Await Is Still Promises

Under the hood, async/await uses Promises:

async function example() {
  return 'value';
}

// Same as:
function example() {
  return Promise.resolve('value');
}

Key Takeaways

  • async makes a function return a Promise
  • await pauses execution until Promise settles
  • ✅ Only use await inside async functions
  • ✅ Makes async code look synchronous
  • ✅ Better readability and debugging
  • ✅ Use try/catch for error handling

Next Steps

You've completed the core lessons! Continue exploring advanced topics and real-world patterns in the remaining sections.