Skip to main content
Course/Module 6/Topic 2 of 3Intermediate

JavaScript Async/Await

Master async/await syntax, the modern way to work with promises that makes asynchronous code look and behave more like synchronous code

50 minBy Priygop TeamLast updated: Feb 2026

Async/Await Basics

Async/await is built on top of promises and provides a more intuitive way to write asynchronous code. It allows you to write promise-based code as if it were synchronous, without blocking the main thread.

Async Function Examples

Example
// Basic async function
async function fetchUserData(userId) {
    try {
        const response = await fetch(`https://api.example.com/users/${userId}`);
        
        if (!response.ok) {
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const userData = await response.json();
        return userData;
    } catch (error) {
        console.error('Error fetching user:', error.message);
        throw error;
    }
}

// Async function with multiple awaits
async function processUser(userId) {
    try {
        // Fetch user data
        const user = await fetchUserData(userId);
        console.log('User fetched:', user);
        
        // Fetch user posts
        const posts = await fetchUserPosts(userId);
        console.log('Posts fetched:', posts);
        
        // Fetch user comments
        const comments = await fetchUserComments(userId);
        console.log('Comments fetched:', comments);
        
        return {
            user,
            posts,
            comments
        };
    } catch (error) {
        console.error('Error processing user:', error.message);
        throw error;
    }
}

// Async function with parallel execution
async function processUserParallel(userId) {
    try {
        // Execute all promises in parallel
        const [user, posts, comments] = await Promise.all([
            fetchUserData(userId),
            fetchUserPosts(userId),
            fetchUserComments(userId)
        ]);
        
        return { user, posts, comments };
    } catch (error) {
        console.error('Error in parallel processing:', error.message);
        throw error;
    }
}

// Async function with conditional logic
async function fetchDataWithFallback(primaryUrl, fallbackUrl) {
    try {
        const response = await fetch(primaryUrl);
        if (response.ok) {
            return await response.json();
        }
    } catch (error) {
        console.log('Primary URL failed, trying fallback...');
    }
    
    try {
        const response = await fetch(fallbackUrl);
        if (response.ok) {
            return await response.json();
        }
    } catch (error) {
        throw new Error('Both URLs failed');
    }
}

// Async function with timeout
async function fetchWithTimeout(url, timeout = 5000) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);
    
    try {
        const response = await fetch(url, {
            signal: controller.signal
        });
        
        clearTimeout(timeoutId);
        return await response.json();
    } catch (error) {
        clearTimeout(timeoutId);
        if (error.name === 'AbortError') {
            throw new Error('Request timeout');
        }
        throw error;
    }
}

// Async function with retry logic
async function fetchWithRetry(url, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            const response = await fetch(url);
            if (response.ok) {
                return await response.json();
            }
        } catch (error) {
            if (attempt === maxRetries) {
                throw error;
            }
            console.log(`Attempt ${attempt} failed, retrying...`);
            await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
        }
    }
}

// Async function in loops
async function processItems(items) {
    const results = [];
    
    // Sequential processing
    for (const item of items) {
        const result = await processItem(item);
        results.push(result);
    }
    
    return results;
}

async function processItemsParallel(items) {
    // Parallel processing
    const promises = items.map(item => processItem(item));
    return await Promise.all(promises);
}

// Async function with error boundaries
async function safeAsyncOperation(operation) {
    try {
        return await operation();
    } catch (error) {
        console.error('Operation failed:', error.message);
        return null;
    }
}

Practice Exercise: Async/Await

Example
// Exercise: Build an Async Data Processor
class AsyncDataProcessor {
    constructor() {
        this.cache = new Map();
        this.processing = new Set();
    }
    
    async processData(data, processor) {
        const cacheKey = JSON.stringify(data);
        
        if (this.cache.has(cacheKey)) {
            console.log('Returning cached result');
            return this.cache.get(cacheKey);
        }
        
        if (this.processing.has(cacheKey)) {
            console.log('Waiting for ongoing processing...');
            while (this.processing.has(cacheKey)) {
                await new Promise(resolve => setTimeout(resolve, 100));
            }
            return this.cache.get(cacheKey);
        }
        
        this.processing.add(cacheKey);
        
        try {
            const result = await processor(data);
            this.cache.set(cacheKey, result);
            return result;
        } finally {
            this.processing.delete(cacheKey);
        }
    }
    
    async batchProcess(items, processor, batchSize = 5) {
        const results = [];
        
        for (let i = 0; i < items.length; i += batchSize) {
            const batch = items.slice(i, i + batchSize);
            const batchPromises = batch.map(item => processor(item));
            const batchResults = await Promise.all(batchPromises);
            results.push(...batchResults);
            
            console.log(`Processed batch ${Math.floor(i / batchSize) + 1}`);
        }
        
        return results;
    }
    
    async processWithProgress(items, processor, onProgress) {
        const results = [];
        let completed = 0;
        
        const promises = items.map(async (item, index) => {
            const result = await processor(item);
            completed++;
            onProgress(completed, items.length, result);
            return result;
        });
        
        return await Promise.all(promises);
    }
}

// Exercise: Build an Async Cache Manager
class AsyncCacheManager {
    constructor() {
        this.cache = new Map();
        this.expiryTimes = new Map();
    }
    
    async get(key) {
        if (this.isExpired(key)) {
            this.delete(key);
            return null;
        }
        
        return this.cache.get(key);
    }
    
    set(key, value, ttl = 60000) { // Default 1 minute TTL
        this.cache.set(key, value);
        this.expiryTimes.set(key, Date.now() + ttl);
    }
    
    delete(key) {
        this.cache.delete(key);
        this.expiryTimes.delete(key);
    }
    
    isExpired(key) {
        const expiryTime = this.expiryTimes.get(key);
        return expiryTime && Date.now() > expiryTime;
    }
    
    async getOrSet(key, fetcher, ttl = 60000) {
        let value = await this.get(key);
        
        if (value === null) {
            value = await fetcher();
            this.set(key, value, ttl);
        }
        
        return value;
    }
    
    clear() {
        this.cache.clear();
        this.expiryTimes.clear();
    }
    
    getStats() {
        return {
            size: this.cache.size,
            keys: Array.from(this.cache.keys())
        };
    }
}

// Exercise: Build an Async Task Scheduler
class AsyncTaskScheduler {
    constructor(maxConcurrent = 3) {
        this.maxConcurrent = maxConcurrent;
        this.running = 0;
        this.queue = [];
    }
    
    async schedule(task, priority = 0) {
        return new Promise((resolve, reject) => {
            this.queue.push({
                task,
                priority,
                resolve,
                reject
            });
            
            this.queue.sort((a, b) => b.priority - a.priority);
            this.process();
        });
    }
    
    async process() {
        if (this.running >= this.maxConcurrent || this.queue.length === 0) {
            return;
        }
        
        const { task, resolve, reject } = this.queue.shift();
        this.running++;
        
        try {
            const result = await task();
            resolve(result);
        } catch (error) {
            reject(error);
        } finally {
            this.running--;
            this.process(); // Process next task
        }
    }
    
    getStats() {
        return {
            running: this.running,
            queued: this.queue.length,
            maxConcurrent: this.maxConcurrent
        };
    }
}

// Test the exercises
const processor = new AsyncDataProcessor();
const cache = new AsyncCacheManager();
const scheduler = new AsyncTaskScheduler(2);

// Test data processor
const data = [1, 2, 3, 4, 5];
const processorFn = async (item) => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    return item * 2;
};

processor.processData(data, processorFn)
    .then(result => console.log('Processed result:', result));

// Test cache manager
cache.getOrSet('user:123', async () => {
    await new Promise(resolve => setTimeout(resolve, 1000));
    return { id: 123, name: 'John' };
})
.then(user => console.log('Cached user:', user));

// Test task scheduler
const tasks = [
    () => new Promise(resolve => setTimeout(() => resolve('Task 1'), 2000)),
    () => new Promise(resolve => setTimeout(() => resolve('Task 2'), 1000)),
    () => new Promise(resolve => setTimeout(() => resolve('Task 3'), 1500)),
    () => new Promise(resolve => setTimeout(() => resolve('Task 4'), 500))
];

tasks.forEach((task, index) => {
    scheduler.schedule(task, index)
        .then(result => console.log(`Scheduled task ${index + 1}: ${result}`));
});
Chat on WhatsApp
Priygop - Leading Professional Development Platform | Expert Courses & Interview Prep