javascript
examples
examples.js⚡javascript
// ============================================
// 18.1 Promise Combinators - Examples
// ============================================
// Helper function to simulate async operations
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function fetchData(id, time, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(new Error(`Failed to fetch ${id}`));
} else {
resolve({ id, data: `Data for ${id}` });
}
}, time);
});
}
// --------------------------------------------
// 1. Promise.all() - Basic Usage
// --------------------------------------------
async function promiseAllBasic() {
console.log('=== Promise.all Basic ===');
const promises = [
fetchData('user', 100),
fetchData('posts', 200),
fetchData('comments', 150),
];
const startTime = Date.now();
const results = await Promise.all(promises);
const elapsed = Date.now() - startTime;
console.log('Results:', results);
console.log(`Time: ${elapsed}ms (parallel, not 450ms)`);
// Time should be ~200ms (max of all), not 450ms (sum)
}
// promiseAllBasic();
// --------------------------------------------
// 2. Promise.all() - Order Preserved
// --------------------------------------------
async function promiseAllOrder() {
console.log('\n=== Promise.all Order ===');
// Even though they complete in different order...
const promises = [
delay(300).then(() => 'slow'),
delay(100).then(() => 'fast'),
delay(200).then(() => 'medium'),
];
const results = await Promise.all(promises);
console.log('Results in original order:', results);
// ['slow', 'fast', 'medium'] - NOT completion order
}
// promiseAllOrder();
// --------------------------------------------
// 3. Promise.all() - Failure Behavior
// --------------------------------------------
async function promiseAllFailure() {
console.log('\n=== Promise.all Failure ===');
try {
const results = await Promise.all([
fetchData('user', 100),
fetchData('posts', 50, true), // This will fail
fetchData('comments', 150),
]);
console.log('Results:', results);
} catch (error) {
console.log('Promise.all failed:', error.message);
// Fails fast - doesn't wait for others
}
}
// promiseAllFailure();
// --------------------------------------------
// 4. Promise.all() - Practical: Fetch Multiple APIs
// --------------------------------------------
async function fetchMultipleAPIs() {
console.log('\n=== Fetch Multiple APIs ===');
// Simulate API calls
const apis = {
users: () => delay(100).then(() => [{ id: 1, name: 'Alice' }]),
products: () => delay(150).then(() => [{ id: 1, name: 'Widget' }]),
orders: () => delay(80).then(() => [{ id: 1, total: 99.99 }]),
};
const [users, products, orders] = await Promise.all([
apis.users(),
apis.products(),
apis.orders(),
]);
console.log('Users:', users);
console.log('Products:', products);
console.log('Orders:', orders);
}
// fetchMultipleAPIs();
// --------------------------------------------
// 5. Promise.allSettled() - Basic Usage
// --------------------------------------------
async function promiseAllSettledBasic() {
console.log('\n=== Promise.allSettled Basic ===');
const results = await Promise.allSettled([
fetchData('user', 100),
fetchData('posts', 50, true), // Fails
fetchData('comments', 150),
]);
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
console.log(`Promise ${i}: Success -`, result.value);
} else {
console.log(`Promise ${i}: Failed -`, result.reason.message);
}
});
}
// promiseAllSettledBasic();
// --------------------------------------------
// 6. Promise.allSettled() - Extracting Results
// --------------------------------------------
async function extractSettledResults() {
console.log('\n=== Extract Settled Results ===');
const results = await Promise.allSettled([
Promise.resolve(1),
Promise.reject(new Error('Failed')),
Promise.resolve(3),
]);
// Get only successful results
const successes = results
.filter((r) => r.status === 'fulfilled')
.map((r) => r.value);
// Get only failures
const failures = results
.filter((r) => r.status === 'rejected')
.map((r) => r.reason);
console.log('Successes:', successes); // [1, 3]
console.log('Failures:', failures); // [Error: Failed]
}
// extractSettledResults();
// --------------------------------------------
// 7. Promise.allSettled() - Partial Success
// --------------------------------------------
async function partialSuccessHandling() {
console.log('\n=== Partial Success Handling ===');
async function fetchWithFallback(urls) {
const results = await Promise.allSettled(
urls.map((url) =>
delay(Math.random() * 200).then(() => {
if (Math.random() > 0.5) throw new Error(`Failed: ${url}`);
return { url, data: 'content' };
})
)
);
const successful = results
.filter((r) => r.status === 'fulfilled')
.map((r) => r.value);
const failed = results
.filter((r) => r.status === 'rejected')
.map((r) => r.reason.message);
return { successful, failed };
}
const { successful, failed } = await fetchWithFallback([
'/api/1',
'/api/2',
'/api/3',
'/api/4',
]);
console.log('Loaded:', successful.length, 'items');
console.log('Failed:', failed.length, 'items');
}
// partialSuccessHandling();
// --------------------------------------------
// 8. Promise.race() - Basic Usage
// --------------------------------------------
async function promiseRaceBasic() {
console.log('\n=== Promise.race Basic ===');
const result = await Promise.race([
delay(300).then(() => 'slow'),
delay(100).then(() => 'fast'),
delay(200).then(() => 'medium'),
]);
console.log('Winner:', result); // 'fast'
}
// promiseRaceBasic();
// --------------------------------------------
// 9. Promise.race() - Timeout Pattern
// --------------------------------------------
async function timeoutPattern() {
console.log('\n=== Timeout Pattern ===');
function timeout(ms) {
return new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout!')), ms)
);
}
async function fetchWithTimeout(fetchPromise, ms) {
return Promise.race([fetchPromise, timeout(ms)]);
}
try {
// Fast operation - succeeds
const fast = await fetchWithTimeout(
delay(100).then(() => 'Fast result'),
500
);
console.log('Fast:', fast);
// Slow operation - times out
const slow = await fetchWithTimeout(
delay(1000).then(() => 'Slow result'),
500
);
console.log('Slow:', slow);
} catch (error) {
console.log('Error:', error.message); // 'Timeout!'
}
}
// timeoutPattern();
// --------------------------------------------
// 10. Promise.race() - First Response from Multiple Servers
// --------------------------------------------
async function fastestServer() {
console.log('\n=== Fastest Server ===');
function fetchFromServer(server, latency) {
return delay(latency).then(() => ({
server,
data: 'Response data',
latency,
}));
}
const result = await Promise.race([
fetchFromServer('server-us', 150),
fetchFromServer('server-eu', 80),
fetchFromServer('server-asia', 200),
]);
console.log(`Fastest: ${result.server} (${result.latency}ms)`);
}
// fastestServer();
// --------------------------------------------
// 11. Promise.any() - Basic Usage
// --------------------------------------------
async function promiseAnyBasic() {
console.log('\n=== Promise.any Basic ===');
const result = await Promise.any([
delay(300).then(() => 'slow'),
delay(100).then(() => 'fast'),
delay(200).then(() => 'medium'),
]);
console.log('First to fulfill:', result); // 'fast'
}
// promiseAnyBasic();
// --------------------------------------------
// 12. Promise.any() - Ignores Rejections
// --------------------------------------------
async function promiseAnyIgnoresRejections() {
console.log('\n=== Promise.any Ignores Rejections ===');
const result = await Promise.any([
Promise.reject(new Error('Error 1')),
delay(200).then(() => 'Success!'),
Promise.reject(new Error('Error 2')),
]);
console.log('Result:', result); // 'Success!'
// Rejections are ignored if at least one fulfills
}
// promiseAnyIgnoresRejections();
// --------------------------------------------
// 13. Promise.any() - All Reject = AggregateError
// --------------------------------------------
async function promiseAnyAllReject() {
console.log('\n=== Promise.any All Reject ===');
try {
await Promise.any([
Promise.reject(new Error('Error 1')),
Promise.reject(new Error('Error 2')),
Promise.reject(new Error('Error 3')),
]);
} catch (error) {
console.log('Error type:', error.constructor.name); // AggregateError
console.log(
'Errors:',
error.errors.map((e) => e.message)
);
// ['Error 1', 'Error 2', 'Error 3']
}
}
// promiseAnyAllReject();
// --------------------------------------------
// 14. Promise.any() - Fallback Sources
// --------------------------------------------
async function fallbackSources() {
console.log('\n=== Fallback Sources ===');
async function fetchFromCDN(cdn) {
await delay(Math.random() * 100);
if (cdn === 'cdn1') throw new Error('CDN1 down');
return { cdn, content: 'Resource content' };
}
try {
const result = await Promise.any([
fetchFromCDN('cdn1'), // Will fail
fetchFromCDN('cdn2'),
fetchFromCDN('cdn3'),
]);
console.log(`Got content from ${result.cdn}`);
} catch (error) {
console.log('All CDNs failed');
}
}
// fallbackSources();
// --------------------------------------------
// 15. Combining Combinators
// --------------------------------------------
async function combinedExample() {
console.log('\n=== Combined Example ===');
// Fetch from multiple endpoints, timeout each, get results for all
async function fetchWithTimeout(url, ms) {
const timeout = delay(ms).then(() => {
throw new Error(`Timeout: ${url}`);
});
const fetch = delay(Math.random() * 200).then(() => ({
url,
data: 'content',
}));
return Promise.race([fetch, timeout]);
}
const urls = ['/api/a', '/api/b', '/api/c', '/api/d'];
// Use allSettled to handle partial failures with timeout
const results = await Promise.allSettled(
urls.map((url) => fetchWithTimeout(url, 100))
);
const succeeded = results.filter((r) => r.status === 'fulfilled');
const failed = results.filter((r) => r.status === 'rejected');
console.log(`Succeeded: ${succeeded.length}, Failed: ${failed.length}`);
}
// combinedExample();
// --------------------------------------------
// Run Examples
// --------------------------------------------
async function runAll() {
await promiseAllBasic();
await promiseAllOrder();
await promiseAllFailure();
await fetchMultipleAPIs();
await promiseAllSettledBasic();
await extractSettledResults();
await promiseRaceBasic();
await timeoutPattern();
await promiseAnyBasic();
await promiseAnyIgnoresRejections();
await promiseAnyAllReject();
await combinedExample();
}
// Uncomment to run all examples:
// runAll();
console.log('Promise Combinators Examples - Uncomment runAll() to execute');