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:
- The
await
keyword can only be used inside a function marked asasync
. await
is placed before a call that returns a promise (e.g.,fetch()
orresponse.json()
).await
"pauses" the execution of theasync
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
orasync
, 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
🚀 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 theasync/await
syntax.- Try adding another request to
Promise.all()
(e.g., tohttps://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 usingawait
is marked asasync
.- The variable contains
[object Promise]
: You forgot to putawait
before the function that returns a promise.