Skip to content

Chapter 4.5: Async/await vs Promise

Study time: 30 minutes


1. Asynchrony: Two Ways to Manage "Space Communication"

Imagine Mission Control sends a command to Mars. The response will only arrive after several minutes. How do you organize work during this time?

Method 1: "Callback Protocol" (Promise with .then()) You send a command and give an instruction: "WHEN the response arrives, THEN execute this function." This is like a chain of events.

Method 2: "Standby Mode" (Async/await) You say: "I will AWAIT the response to this command, but I will not block the other control panels." You are essentially pausing the execution of this specific task, allowing the rest of Mission Control to continue working.

Both methods solve the same problem — managing asynchronous operations. async/await is just a more modern and readable syntax that works "on top" of promises.

💡 Space Analogy:

  • Promise with .then(): It's like writing on a sticky note: "When the Mars rover sends a photo, pass it to the analysis department."
  • Async/await: It's like telling an assistant: "Wait for the photo from the Mars rover, and in the meantime, I'll do the calculations for the launch of a new rocket."

2. Promise with .then(): The Classic Command Chain

This is the fundamental way of working with asynchrony in JavaScript, which we used in Chapter 4.1.

Let's recall our first code:

function getIssPositionWithPromises() {
    console.log('Sending request via "Promise" protocol...');

    fetch('http://api.open-notify.org/iss-now.json')
        .then(response => {
            // Stage 1: Response received
            if (!response.ok) {
                throw new Error(`HTTP error: ${response.status}`);
            }
            return response.json(); // Return a new promise
        })
        .then(data => {
            // Stage 2: Data parsed
            console.log('Data received via "Promise" protocol:', data.iss_position);
        })
        .catch(error => {
            // Stage 3 (Error): Something went wrong at any stage
            console.error('Communication failure via "Promise" protocol:', error);
        });

    console.log('...command sent, Mission Control continues to operate...');
}

Pros:

  • Clear chain of actions.
  • Well-suited for simple sequential operations.

Cons:

  • "Callback Hell": With a large number of nested asynchronous operations, the code can turn into a "pyramid" of .then() clauses that is difficult to read.
  • Error handling can be less intuitive.

3. Async/await: The Modern Synchronous Style

async/await is "syntactic sugar" over promises that allows you to write asynchronous code as if it were synchronous.

Rules of use:

  1. The await keyword can only be used inside a function marked as async.
  2. await is placed before a call that returns a promise (e.g., fetch() or response.json()).
  3. await "pauses" the execution of the async function until the promise is resolved, and returns its result.

The same code, rewritten with async/await:

async function getIssPositionWithAsyncAwait() {
    console.log('Sending request via "Async/await" protocol...');

    try {
        // Stage 1: Wait for the server response
        const response = await fetch('http://api.open-notify.org/iss-now.json');

        if (!response.ok) {
            throw new Error(`HTTP error: ${response.status}`);
        }

        // Stage 2: Wait for the response body to be converted to JSON
        const data = await response.json();

        console.log('Data received via "Async/await" protocol:', data.iss_position);
    } catch (error) {
        // Stage 3 (Error): Catch any error from the try block
        console.error('Communication failure via "Async/await" protocol:', error);
    }

    console.log('...command sent, Mission Control continues to operate...');
}

Pros:

  • Readability: The code looks almost like regular synchronous code, making it easy to read from top to bottom.
  • Error Handling: Uses the standard and familiar try...catch block.
  • Debugging: Much easier to debug, as you can set breakpoints on each line with await.

Cons:

  • It's easy to forget await or async, which will lead to errors.

4. When to Use Which Protocol?

Situation Recommended Approach Why?
Most cases async/await The code is cleaner, easier to read and debug. It is the modern standard.
Simple chain of 1-2 actions Promise with .then() Quite suitable, the code remains compact.
Parallel execution of multiple requests Promise.all() This method allows you to run multiple promises simultaneously and wait for all of them to complete. async/await works great with it.

Example with Promise.all():

async function getParallelData() {
    try {
        // Start both requests at the same time
        const [shipsResponse, launchesResponse] = await Promise.all([
            fetch('https://api.spacexdata.com/v4/rockets'),
            fetch('https://api.spacexdata.com/v4/launches/latest')
        ]);

        if (!shipsResponse.ok || !launchesResponse.ok) {
            throw new Error('One of the requests failed!');
        }

        const rockets = await shipsResponse.json();
        const latestLaunch = await launchesResponse.json();

        console.log(`Total rockets in the fleet: ${rockets.length}`);
        console.log(`Latest launch: ${latestLaunch.name}`);
    } catch (error) {
        console.error('Error getting parallel data:', error);
    }
}


Quiz to Reinforce

1. `async/await` is...

2. What keyword is mandatory for a function that uses `await` inside it?

3. The main advantage of `async/await` over `.then()` is:

4. What happens if you forget `await` before `fetch()` inside an `async` function?

5. `Promise.all()` is used for:


🚀 Chapter Summary:

You have studied two syntaxes for managing asynchronous operations and understood why async/await is preferred in most modern projects.

  • 🔗 You have refreshed your knowledge of Promise with .then().
  • 🛠️ You have a deep understanding of how async/await works and its advantages.
  • ⚡ You have learned about Promise.all for executing parallel requests.

Communication protocols studied! In the final chapter of this section, we will bring all our knowledge together and complete our "Mission Control Center" by creating a full-fledged interface for all CRUD operations.

📌 Practice:

  • Rewrite all the functions in your app.js that still use .then() to the async/await syntax.
  • Try adding another request to Promise.all() (e.g., to https://api.spacexdata.com/v4/starlink) and display the data.

⚠️ If there are errors:

  • await is only valid in async functions: Make sure the function where you are using await is marked as async.
  • The variable contains [object Promise]: You forgot to put await before the function that returns a promise.