JavaScript Promises
What is a promise in JavaScript?
A promise in JavaScript is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It allows you to handle asynchronous operations more effectively, avoiding callback hell.
What are the states of a promise?
A promise has three states:
- Pending: The initial state; the operation is ongoing.
- Fulfilled: The operation completed successfully, resulting in a resolved value.
- Rejected: The operation failed, resulting in a reason for the failure.
How do you create a promise?
You can create a promise using the Promise constructor, which takes a function with two parameters: resolve and reject.
const myPromise = new Promise((resolve, reject) => {
// Simulate asynchronous operation
const success = true; // Change to false to simulate error
if (success) {
resolve('Operation successful!');
} else {
reject('Operation failed!');
}
});
How do you handle the result of a promise?
You can handle the result of a promise using the then() method for fulfilled promises and the catch() method for rejected promises.
myPromise
.then(result => {
console.log(result); // Outputs: Operation successful!
})
.catch(error => {
console.error(error);
});
What is the finally() method in promises?
The finally() method allows you to execute a block of code after the promise has settled, regardless of whether it was fulfilled or rejected. It is useful for cleanup operations.
myPromise
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
})
.finally(() => {
console.log('Cleanup code here.');
});
Can you explain promise chaining?
Promise chaining allows you to execute a sequence of asynchronous operations by returning a promise from a then() method, which can be followed by another then() method.
function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('Data received');
}, 1000);
});
}
fetchData()
.then(data => {
console.log(data); // Outputs: Data received
return 'Next data'; // Return a new promise
})
.then(nextData => {
console.log(nextData); // Outputs: Next data
});
What are Promise.all() and Promise.race()?
Promise.all() takes an array of promises and returns a single promise that resolves when all of the promises in the array have resolved or rejects if any of the promises reject. Promise.race() returns a promise that resolves or rejects as soon as one of the promises in the array resolves or rejects.
// Promise.all example
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, 'foo'));
const promise3 = 42;
Promise.all([promise1, promise2, promise3])
.then(values => {
console.log(values); // Outputs: [3, 'foo', 42]
});
// Promise.race example
const promiseA = new Promise((resolve) => setTimeout(resolve, 2000, 'A'));
const promiseB = new Promise((resolve) => setTimeout(resolve, 1000, 'B'));
Promise.race([promiseA, promiseB])
.then(value => {
console.log(value); // Outputs: 'B'
});
What is the purpose of the async and await keywords?
The async keyword is used to define an asynchronous function that returns a promise. The await keyword is used within an async function to pause execution until the promise is resolved or rejected, allowing for cleaner and more readable asynchronous code.
async function fetchData() {
const data = await new Promise((resolve) => {
setTimeout(() => {
resolve('Data received');
}, 1000);
});
console.log(data); // Outputs: Data received
}
fetchData();
What are some common mistakes when working with promises?
Common mistakes include:
- Not returning a promise in a chain, leading to unexpected behavior.
- Forgetting to handle errors using
catch(). - Confusing synchronous code with asynchronous code, leading to improper handling of asynchronous results.
- Using
asyncwithout a function returning a promise.