Intermediate 18 min read

Promises and async/await

By the end of this lesson, you'll be able to:

  • Explain what a Promise represents
  • Use async/await syntax to work with asynchronous code
  • Recognize that imperative Apex calls return Promises

Prerequisites: "Modules: Imports and Exports"

What Is a Promise?

A Promise represents a value that will be available later, not immediately — it exists because operations like network calls take real time to complete. A Promise is always in one of three states: pending (still working), fulfilled (succeeded, with a result), or rejected (failed, with an error).

async/await Syntax

async function loadData() {
    const result = await somePromiseReturningFunction();
    console.log(result);
}

await pauses execution within that async function until the Promise resolves, letting you write asynchronous code that reads top-to-bottom like synchronous code — far cleaner than chaining .then() calls.

Running Multiple Promises at Once: Promise.all

await on its own runs one Promise at a time — each await waits for its Promise to finish before the next line runs. When several independent operations don't depend on each other's results, waiting for them one after another wastes time. Promise.all runs them concurrently instead:

const [accounts, contacts] = await Promise.all([
    getAccounts(),
    getContacts(),
]);

Promise.all takes an array of Promises and returns a single Promise that resolves once every one of them has resolved, with an array of their results in the same order the Promises were given. If any one of them rejects, the whole Promise.all rejects immediately. This is the standard pattern whenever a component needs to fire off several independent Apex calls, or persist several independent record updates, without waiting for each one to finish before starting the next.

A Worked LWC Example

import getAccounts from '@salesforce/apex/AccountController.getAccounts';

async handleLoadClick() {
    try {
        const accounts = await getAccounts();
        this.accounts = accounts;
    } catch (error) {
        this.error = error;
    }
}

Every imperative Apex call (as opposed to @wire, covered in Module 7) returns a Promise — this is exactly why async/await matters for LWC specifically, not just as general JavaScript trivia.

Why This Matters in Real Projects

Without understanding Promises, imperative Apex calls look like mysterious, hard-to-predict code. With this foundation in place, Module 7's Apex integration lessons will make immediate sense rather than feeling like new, unrelated syntax.

Exercise

Convert this into an async function using await: function loadCases() { return getCases().then(result => console.log(result)); }

Show hint

async/await replaces .then() chains.

JAVASCRIPT

Exercise

Rewrite this to run both calls concurrently with Promise.all instead of sequentially: const accounts = await getAccounts(); const contacts = await getContacts();

Show hint

Promise.all takes an array of Promises and returns an array of results.

JAVASCRIPT

Exercise

Challenge: explain, as a comment, the three possible states of a Promise.

Show hint

One "in progress" state, and two "done" states.

JAVASCRIPT

Promises and async/await Quiz

1. What does Promise.all([p1, p2]) do?

2. What does a Promise represent?

3. What does the await keyword do inside an async function?

4. Imperative Apex calls in LWC return Promises.

5. What are the three possible states of a Promise?

6. Why does understanding Promises matter specifically for LWC development?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Every imperative Apex call in LWC returns a Promise — understanding what that means, and how async/await makes it readable, is required groundwork before Module 7 makes any sense.