Represent a Future Result
Represent a Future Result
A promise represents an eventual fulfillment value or rejection reason. then schedules its handler after the current synchronous work; returning a value from a handler passes it to the next link.
Before this topic, review Pass an Operation to Another Function if its terms are unfamiliar.
What you’ll learn
- Explain represent a future result through the school example.
- Trace the shown operations and distinguish their result from displayed output.
- Make the practice change and explain its consequence: The promise value changes, while synchronous Start and End still precede its handler.
Work through the school example
This is JavaScript using language features and the host console. Read the initial values, then follow each operation to its displayed result. A declaration names a value, a function call performs an operation, and console.log displays its arguments.
JavaScript · school.js · complete example
console.log("Start");
Promise.resolve(72).then((mark) => console.log(mark));
console.log("End");
Expected output
Start
End
72Run in JavaScript compiler →Introduction to Promises
JavaScript Promises are a powerful way to handle asynchronous operations like network requests, timers, or file access. A Promise represents a value that may be available now, later, or never.
Creating a Promise
A Promise is created using the Promise constructor, which takes a function with two arguments: resolve and reject.
const fetchData = () => {
return new Promise((resolve, reject) => {
let success = true;
setTimeout(() => {
if (success) {
resolve("Data fetched successfully!");
} else {
reject("Failed to fetch data.");
}
}, 1000);
};
fetchData()
.then((data) => console.log(data))
.catch((error) => console.error(error));
Data fetched successfully!
Understanding the Output
In the above example, we used setTimeout to simulate an asynchronous operation. If success is true, the promise is resolved. Otherwise, it's rejected. The .then() method handles the success case, and .catch() handles errors.
Why use Promises?
Without Promises, asynchronous code becomes hard to manage, especially when nested. Promises help avoid callback hell by providing a cleaner and more readable way to handle async operations.
Chaining Promises
One of the main strengths of Promises is chaining. You can return values from a .then() block and pass it to the next .then().
const stepOne = () => {
return new Promise((resolve) => {
setTimeout(() => resolve("Step 1 complete"), 1000);
});
};
const stepTwo = (message) => {
console.log(message);
return new Promise((resolve) => {
setTimeout(() => resolve("Step 2 complete"), 1000);
});
};
const stepThree = (message) => {
console.log(message);
return new Promise((resolve) => {
setTimeout(() => resolve("Step 3 complete"), 1000);
});
};
stepOne()
.then(stepTwo)
.then(stepThree)
.then((finalMessage) => console.log(finalMessage));
Step 1 complete Step 2 complete Step 3 complete
Explanation
Each function returns a Promise. As each Promise resolves, the next one in the chain is called. This pattern is great for running asynchronous tasks in sequence.
What happens if something fails in the chain?
If a Promise in the chain is rejected, the control jumps to the nearest .catch() block.
const faultyStep = () => {
return new Promise((resolve, reject) => {
setTimeout(() => reject("Something went wrong!"), 1000);
});
};
stepOne()
.then(faultyStep)
.then(stepThree)
.catch((error) => console.error("Error caught:", error));
Step 1 complete Error caught: Something went wrong!
Questions to Develop Intuition
Q1: What happens if you forget to return a Promise in a .then()?
A: The next .then() in the chain receives undefined. This can lead to bugs if you're expecting a value or further async operation.
Q2: Can you chain a .catch() after a .then()?
A: Yes. If any previous Promise is rejected, the .catch() block handles the error.
Q3: Is it mandatory to use catch() at the end of a chain?
A: It's not mandatory, but it's good practice to avoid unhandled Promise rejections.
Summary
- A Promise is an object that represents a future value.
.then()is used to handle resolved values,.catch()for errors.- Chaining allows running async tasks sequentially in a readable way.
- Always return Promises when chaining to avoid unexpected behavior.
Recognize the important boundary
A promise is not the result itself. Return nested promises to preserve sequencing, and handle rejection rather than leaving failures unobserved.
Compare the demonstrated ordering with the event loop and promise-handler walkthrough.
Try a small variation
JavaScript · original source for practice
console.log("Start");
Promise.resolve(72).then((mark) => console.log(mark));
console.log("End");
Your task: Replace resolve(72) with resolve(80). Predict the result before running the edited program.
The source is repeated here. If the edit targets the HTML rather than the script, use the markup repeated below; the worked answer also repeats the changed markup.
Worked answer and reasoning
The promise value changes, while synchronous Start and End still precede its handler.
JavaScript · complete worked variation
console.log("Start");
Promise.resolve(80).then((mark) => console.log(mark));
console.log("End");
Expected output
Start
End
80Run in JavaScript compiler →Predict the original program
JavaScript · original program for this question
console.log("Start");
Promise.resolve(72).then((mark) => console.log(mark));
console.log("End");
Keep the useful idea
A promise represents an eventual fulfillment value or rejection reason. then schedules its handler after the current synchronous work; returning a value from a handler passes it to the next link.
Check your variation against this explanation: The promise value changes, while synchronous Start and End still precede its handler.
Use the JavaScript array reference library for individual array operations and boundary tests to check a rule independently.
Reaching the recap and completing the quizzes are separate milestones.