JavaScript Promises
Learn to work with promises, handle asynchronous operations, and manage promise chains for better error handling and code organization
55 min•By Priygop Team•Last updated: Feb 2026
Promise Fundamentals
Promises represent the eventual completion (or failure) of an asynchronous operation and its resulting value. They provide a cleaner alternative to callback-based asynchronous code and help avoid callback hell.
Creating Promises
Example
// Creating promises
// Basic promise
const basicPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Success!');
}, 1000);
});
// Promise with error
const errorPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('Something went wrong!'));
}, 1000);
});
// Promise with conditional logic
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
if (!userId) {
reject(new Error('User ID is required'));
return;
}
// Simulate API call
setTimeout(() => {
const userData = {
id: userId,
name: 'John Doe',
email: 'john@example.com'
};
resolve(userData);
}, 1000);
});
}
// Promise with timeout
function promiseWithTimeout(promise, timeout) {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), timeout)
)
]);
}
// Using promises
basicPromise
.then(result => console.log(result))
.catch(error => console.error(error));
errorPromise
.then(result => console.log(result))
.catch(error => console.error(error.message));
fetchUserData(123)
.then(user => console.log('User:', user))
.catch(error => console.error('Error:', error.message));
// Promise chaining
fetchUserData(123)
.then(user => {
console.log('User fetched:', user);
return fetchUserPosts(user.id);
})
.then(posts => {
console.log('Posts fetched:', posts);
return fetchUserComments(user.id);
})
.then(comments => {
console.log('Comments fetched:', comments);
})
.catch(error => {
console.error('Error in chain:', error.message);
});Promise Methods
Example
// Promise.all - Wait for all promises
const promises = [
fetchUserData(1),
fetchUserData(2),
fetchUserData(3)
];
Promise.all(promises)
.then(users => {
console.log('All users:', users);
})
.catch(error => {
console.error('One of the promises failed:', error);
});
// Promise.allSettled - Wait for all promises to settle
Promise.allSettled(promises)
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Promise ${index} succeeded:`, result.value);
} else {
console.log(`Promise ${index} failed:`, result.reason);
}
});
});
// Promise.race - First promise to settle
const fastPromise = new Promise(resolve => setTimeout(() => resolve('Fast'), 100));
const slowPromise = new Promise(resolve => setTimeout(() => resolve('Slow'), 1000));
Promise.race([fastPromise, slowPromise])
.then(result => console.log('Winner:', result)); // "Fast"
// Promise.any - First promise to fulfill
const errorPromise = new Promise((_, reject) => setTimeout(() => reject('Error'), 500));
const successPromise = new Promise(resolve => setTimeout(() => resolve('Success'), 1000));
Promise.any([errorPromise, successPromise])
.then(result => console.log('First success:', result)) // "Success"
.catch(error => console.log('All promises failed:', error));
// Promise.resolve and Promise.reject
const resolvedPromise = Promise.resolve('Immediate success');
const rejectedPromise = Promise.reject(new Error('Immediate error'));
// Converting callback-based functions to promises
function promisify(fn) {
return function(...args) {
return new Promise((resolve, reject) => {
fn(...args, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
};
}
// Example usage
const fs = require('fs');
const readFileAsync = promisify(fs.readFile);
readFileAsync('file.txt', 'utf8')
.then(content => console.log('File content:', content))
.catch(error => console.error('File read error:', error));Practice Exercise: Promises
Example
// Exercise: Build a Promise-based API Client
class ApiClient {
constructor(baseUrl) {
this.baseUrl = baseUrl;
this.cache = new Map();
}
request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const cacheKey = `${options.method || 'GET'}-${url}`;
// Check cache for GET requests
if (options.method === 'GET' && this.cache.has(cacheKey)) {
return Promise.resolve(this.cache.get(cacheKey));
}
return fetch(url, {
headers: {
'Content-Type': 'application/json',
...options.headers
},
...options
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
})
.then(data => {
// Cache GET responses
if (options.method === 'GET') {
this.cache.set(cacheKey, data);
}
return data;
});
}
get(endpoint) {
return this.request(endpoint, { method: 'GET' });
}
post(endpoint, data) {
return this.request(endpoint, {
method: 'POST',
body: JSON.stringify(data)
});
}
put(endpoint, data) {
return this.request(endpoint, {
method: 'PUT',
body: JSON.stringify(data)
});
}
delete(endpoint) {
return this.request(endpoint, { method: 'DELETE' });
}
clearCache() {
this.cache.clear();
}
}
// Exercise: Build a Promise Queue
class PromiseQueue {
constructor() {
this.queue = [];
this.running = false;
}
add(task) {
return new Promise((resolve, reject) => {
this.queue.push({
task,
resolve,
reject
});
if (!this.running) {
this.process();
}
});
}
async process() {
this.running = true;
while (this.queue.length > 0) {
const { task, resolve, reject } = this.queue.shift();
try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
}
}
this.running = false;
}
getLength() {
return this.queue.length;
}
clear() {
this.queue = [];
}
}
// Exercise: Build a Retry Mechanism
function retry(fn, maxAttempts = 3, delay = 1000) {
return new Promise((resolve, reject) => {
let attempts = 0;
function attempt() {
attempts++;
fn()
.then(resolve)
.catch(error => {
if (attempts >= maxAttempts) {
reject(error);
} else {
console.log(`Attempt ${attempts} failed, retrying in ${delay}ms...`);
setTimeout(attempt, delay);
}
});
}
attempt();
});
}
// Test the exercises
const api = new ApiClient('https://api.example.com');
// Test API client
api.get('/users')
.then(users => console.log('Users:', users))
.catch(error => console.error('API error:', error));
// Test promise queue
const queue = new PromiseQueue();
queue.add(() => new Promise(resolve => setTimeout(() => resolve('Task 1'), 1000)));
queue.add(() => new Promise(resolve => setTimeout(() => resolve('Task 2'), 500)));
queue.add(() => new Promise(resolve => setTimeout(() => resolve('Task 3'), 200)));
// Test retry mechanism
const unreliableFunction = () => {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve('Success!');
} else {
reject(new Error('Random failure'));
}
});
};
retry(unreliableFunction, 3, 1000)
.then(result => console.log('Retry succeeded:', result))
.catch(error => console.error('Retry failed:', error));