Promises
What is a Promise?
A Promise is an object representing the eventual completion or failure of an asynchronous operation. It's a cleaner alternative to callbacks for handling async code.
Try Promises
Code Editor
Console Output
Click "Run" to execute your code...
Example 1: Creating and Using Promises
// Creating a Promise
const myPromise = new Promise((resolve, reject) => {
const success = true;
setTimeout(() => {
if (success) {
resolve('Operation successful!');
} else {
reject('Operation failed!');
}
}, 1000);
});
// Using the Promise
myPromise
.then(result => {
console.log(result); // Operation successful!
})
.catch(error => {
console.error(error);
});
// Promise states: pending, fulfilled, rejected
const promise1 = new Promise((resolve) => {
setTimeout(() => resolve('Done!'), 1000);
});
console.log(promise1); // Promise { <pending> }
promise1.then(result => {
console.log(result); // Done!
console.log(promise1); // Promise { <fulfilled>: 'Done!' }
});Example 2: Promise Chaining
// Chaining promises
function fetchUser(userId) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ id: userId, name: 'John Doe' });
}, 1000);
});
}
function fetchPosts(user) {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ id: 1, title: 'Post 1', userId: user.id },
{ id: 2, title: 'Post 2', userId: user.id }
]);
}, 1000);
});
}
function fetchComments(posts) {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ postId: posts[0].id, text: 'Great post!' },
{ postId: posts[1].id, text: 'Nice article!' }
]);
}, 1000);
});
}
// Clean promise chain
fetchUser(1)
.then(user => {
console.log('User:', user);
return fetchPosts(user);
})
.then(posts => {
console.log('Posts:', posts);
return fetchComments(posts);
})
.then(comments => {
console.log('Comments:', comments);
})
.catch(error => {
console.error('Error:', error);
})
.finally(() => {
console.log('All operations complete!');
});Example 3: Promise.all() and Promise.race()
// Promise.all - waits for all promises to resolve
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve) => {
setTimeout(() => resolve('foo'), 1000);
});
const promise3 = new Promise((resolve) => {
setTimeout(() => resolve('bar'), 500);
});
Promise.all([promise1, promise2, promise3])
.then(values => {
console.log(values); // [3, 'foo', 'bar']
});
// If any promise rejects, Promise.all rejects
const promises = [
Promise.resolve(1),
Promise.reject(new Error('Failed!')),
Promise.resolve(3)
];
Promise.all(promises)
.then(results => console.log(results))
.catch(error => console.error('Error:', error.message)); // Error: Failed!
// Promise.race - resolves/rejects with first settled promise
const fast = new Promise((resolve) => {
setTimeout(() => resolve('Fast'), 500);
});
const slow = new Promise((resolve) => {
setTimeout(() => resolve('Slow'), 1000);
});
Promise.race([fast, slow])
.then(result => console.log(result)); // Fast
// Promise.allSettled - waits for all, doesn't short-circuit
const mixed = [
Promise.resolve(1),
Promise.reject('Error'),
Promise.resolve(3)
];
Promise.allSettled(mixed)
.then(results => {
console.log(results);
// [
// { status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: 'Error' },
// { status: 'fulfilled', value: 3 }
// ]
});
// Promise.any - resolves with first fulfilled promise
const p1 = Promise.reject('Error 1');
const p2 = new Promise((resolve) => setTimeout(() => resolve('Success'), 500));
const p3 = new Promise((resolve) => setTimeout(() => resolve('Also Success'), 1000));
Promise.any([p1, p2, p3])
.then(result => console.log(result)); // SuccessExample 4: Error Handling in Promises
// Basic error handling
const riskyOperation = new Promise((resolve, reject) => {
const random = Math.random();
if (random > 0.5) {
resolve(`Success! Random: ${random}`);
} else {
reject(new Error(`Failed! Random: ${random}`));
}
});
riskyOperation
.then(result => console.log(result))
.catch(error => console.error('Caught:', error.message));
// Multiple catch blocks
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('HTTP error');
}
return response.json();
})
.catch(error => {
console.error('Network error:', error);
throw error; // Re-throw to next catch
})
.then(data => {
// Process data
if (!data.valid) {
throw new Error('Invalid data');
}
return data;
})
.catch(error => {
console.error('Processing error:', error);
});
// Error recovery
function fetchWithRetry(url, retries = 3) {
return fetch(url)
.catch(error => {
if (retries > 0) {
console.log(`Retrying... (${retries} attempts left)`);
return fetchWithRetry(url, retries - 1);
}
throw error;
});
}
// Always use .catch() or try/catch with async/await
// to prevent unhandled promise rejectionsExample 5: Converting Callbacks to Promises
// Old callback style
function oldStyleAsync(value, callback) {
setTimeout(() => {
if (value > 0) {
callback(null, value * 2);
} else {
callback(new Error('Value must be positive'), null);
}
}, 1000);
}
// Promisified version
function promisifiedAsync(value) {
return new Promise((resolve, reject) => {
oldStyleAsync(value, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
// Usage
promisifiedAsync(5)
.then(result => console.log('Result:', result)) // Result: 10
.catch(error => console.error('Error:', error));
// Generic promisify function
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
};
}
const asyncFn = promisify(oldStyleAsync);
asyncFn(10)
.then(result => console.log(result)) // 20
.catch(error => console.error(error));
// Async/await with promises (modern approach)
async function modernAsync() {
try {
const result1 = await promisifiedAsync(5);
console.log('Result 1:', result1);
const result2 = await promisifiedAsync(result1);
console.log('Result 2:', result2);
return result2;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
modernAsync();Key Points
- Promises have three states: pending, fulfilled, rejected
- Use .then() for success, .catch() for errors, .finally() for cleanup
- Promise chains allow sequential async operations
- Promise.all() runs promises in parallel, waits for all
- Promise.race() resolves/rejects with first settled promise
- Always handle errors to avoid unhandled rejections
- Async/await is syntactic sugar over promises