17.3 Programming Activity: Asynchronous Programming Practices (20 mins)
Objective:
Illustrate key concepts of asynchronous programming by writing JavaScript programs that simulate real-world tasks using callbacks, promises, and async/await.
Students will practice:
Writing functions to perform asynchronous tasks.
Implementing callbacks, promises, and async/await.
Comparing the readability and usability of each approach.
Task: Simulate a Bookstore Operations
Simulate the following asynchronous operations:
Get list of books: Fetch a list of available books (simulate with a delay).
Get book details: Fetch details of a selected book (simulate with a delay).
Place an order: Place an order for the selected book (simulate with a delay).
Students will implement these operations using:
Callbacks
Promises
Async/Await
Step-by-Step Procedures
1. Setup the Asynchronous Task Functions
Define three asynchronous functions using setTimeout to simulate delays:
function getBooks(callback) {
setTimeout(() => {
callback(null, ['Book 1', 'Book 2', 'Book 3']);
}, 1000); // Simulates fetching books
}
function getBookDetails(book, callback) {
setTimeout(() => {
if (!book) {
callback('Book not found', null);
} else {
callback(null, { title: book, author: 'Author Name', price: 20 });
}
}, 1500); // Simulates fetching book details
}
function placeOrder(bookDetails, callback) {
setTimeout(() => {
if (!bookDetails) {
callback('Invalid book details', null);
} else {
callback(null, `Order placed for ${bookDetails.title}`);
}
}, 2000); // Simulates placing an order
}2. Task 1: Using Callbacks
Implement the operations using nested callbacks:
Fetch the list of books.
Select a book and fetch its details.
Place an order for the selected book.
Solution:
getBooks((err, books) => {
if (err) {
console.error(err);
return;
}
console.log('Books:', books);
const selectedBook = books[1]; // Select the second book
getBookDetails(selectedBook, (err, bookDetails) => {
if (err) {
console.error(err);
return;
}
console.log('Book Details:', bookDetails);
placeOrder(bookDetails, (err, orderMessage) => {
if (err) {
console.error(err);
return;
}
console.log(orderMessage);
});
});
});3. Task 2: Refactor Using Promises
Modify the task functions to return promises instead of using callbacks:
function getBooks() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(['Book 1', 'Book 2', 'Book 3']);
}, 1000);
});
}
function getBookDetails(book) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (!book) {
reject('Book not found');
} else {
resolve({ title: book, author: 'Author Name', price: 20 });
}
}, 1500);
});
}
function placeOrder(bookDetails) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (!bookDetails) {
reject('Invalid book details');
} else {
resolve(`Order placed for ${bookDetails.title}`);
}
}, 2000);
});
}Solution Using Promises:
getBooks()
.then((books) => {
console.log('Books:', books);
return getBookDetails(books[1]); // Select the second book
})
.then((bookDetails) => {
console.log('Book Details:', bookDetails);
return placeOrder(bookDetails);
})
.then((orderMessage) => {
console.log(orderMessage);
})
.catch((error) => {
console.error(error);
});4. Task 3: Refactor Using Async/Await
Use async/await to make the code more readable and linear.
Solution Using Async/Await:
async function processOrder() {
try {
const books = await getBooks();
console.log('Books:', books);
const bookDetails = await getBookDetails(books[1]); // Select the second book
console.log('Book Details:', bookDetails);
const orderMessage = await placeOrder(bookDetails);
console.log(orderMessage);
} catch (error) {
console.error(error);
}
}
processOrder();Comparing the Techniques
Callbacks
Simple and easy for one or two tasks.
Callback hell for nested tasks.
Promises
Handles chaining and errors cleanly.
Slightly more verbose than async/await.
Async/Await
Linear and synchronous-like code flow.
Requires modern JavaScript support.
Expected Outcomes:
Students will understand the differences in readability and usability of callbacks, promises, and async/await.
Students will be able to simulate asynchronous operations and handle errors effectively.
Gain hands-on experience in refactoring asynchronous code for improved maintainability.
Last updated