Refactor Complex Nested Callback Code to Async/Await in JavaScript
Improve code quality by refactoring a deeply nested callback-based asynchronous function into a clean, readable async/await structure, while maintaining identical functionality.
Challenge prompt
You are given a JavaScript function that performs multiple asynchronous database fetches using nested callbacks, resulting in complex callback hell. Your task is to refactor this function into a clean async/await implementation without changing its behavior or output. Ensure proper error handling and maintain the logical order of asynchronous calls.
Guidance
- • Convert callback-based functions into promises or use promisified versions.
- • Use async/await to linearize asynchronous logic and avoid deeply nested callbacks.
- • Keep the error handling intact by using try/catch blocks.
- • Preserve the original data flow and output format.
Hints
- • Wrap each asynchronous call that uses callbacks into a promise if it doesn't already return one.
- • Remember that async functions always return promises, which you can await sequentially.
- • Pay attention to where errors are handled and replicate that behavior with try/catch.
Starter code
function fetchUserData(userId, callback) {
getUser(userId, function(err, user) {
if (err) return callback(err);
getUserPosts(user.id, function(err, posts) {
if (err) return callback(err);
getCommentsForPosts(posts, function(err, comments) {
if (err) return callback(err);
callback(null, { user, posts, comments });
});
});
});
}
// Simulated async functions
function getUser(id, cb) {
setTimeout(() => cb(null, { id, name: 'Alice' }), 100);
}
function getUserPosts(userId, cb) {
setTimeout(() => cb(null, [{ id: 1, content: 'Hello World' }, { id: 2, content: 'Another post' }]), 100);
}
function getCommentsForPosts(posts, cb) {
setTimeout(() => cb(null, [{ postId: 1, text: 'Nice post!' }, { postId: 2, text: 'Thanks for sharing' }]), 100);
}Expected output
{ user: { id: 1, name: 'Alice' }, posts: [{ id: 1, content: 'Hello World' }, { id: 2, content: 'Another post' }], comments: [{ postId: 1, text: 'Nice post!' }, { postId: 2, text: 'Thanks for sharing' }] }
Core concepts
Challenge a Friend
Send this duel to someone else and see if they can solve it.