A comprehensive learning repository demonstrating 6 different approaches to handling asynchronous operations in Node.js.
This repository teaches you how to handle asynchronous operations in Node.js through a practical example: reading a markdown file, converting it to HTML, and saving it to a database. You'll see the same workflow implemented using different async patterns, from basic callbacks to modern async
/await
.
By the end of this tutorial, you'll understand:
- The evolution of async patterns in JavaScript/Node.js
- How to handle errors in different async approaches
- The pros and cons of each pattern
- When to use each approach in real-world applications
- How to avoid "callback hell" and write cleaner async code
async-in-node/
├── approaches/ # 6 different async implementations
│ ├── 1-callbacks.js # Traditional callback pattern
│ ├── 1b-callbacks-refactored.js # Refactored callbacks (avoiding callback hell)
│ ├── 2-promises.js # Promise-based approach
│ ├── 3-promise-all.js # Parallel execution with Promise.all()
│ ├── 4-async-await.js # Modern `async`/`await` pattern
│ └── 4b-async-await-promise-all.js # `async`/`await` with parallel execution
├── mocks/ # Mock database for simulation
│ └── db.js
├── constants/ # Shared constants
│ └── constants.js
├── blog-posts/ # Sample markdown content
│ └── my-first-feature-article.md
└── package.json
- Node.js (version 14 or higher)
- Clone this repository:
git clone <repository-url>
cd async-in-node
- Install dependencies:
npm install
Each approach can be run independently. Navigate to the project root and run:
# Approach 1: Callbacks
node approaches/1-callbacks.js
# Approach 1b: Refactored Callbacks
node approaches/1b-callbacks-refactored.js
# Approach 2: Promises
node approaches/2-promises.js
# Approach 3: Promise.all (Parallel)
node approaches/3-promise-all.js
# Approach 4: async/await
node approaches/4-async-await.js
# Approach 4b: async/await with Promise.all
node approaches/4b-async-await-promise-all.js
The Traditional Way
- Uses nested callback functions
- Prone to "callback hell" with deep nesting
- Error handling with callback pattern
- Best for: Understanding the fundamentals
Cleaner Callback Pattern
- Same functionality as approach 1, but with better structure
- Demonstrates how to avoid deep nesting
- Best for: Learning callback best practices
The Bridge to Modern Async
- Uses Promise chains with
.then()
and.catch()
- Cleaner error handling
- Avoids callback hell
- Best for: Understanding Promise fundamentals
Parallel Execution
- Runs multiple async operations simultaneously
- Faster execution when operations are independent
- All-or-nothing error handling
- Best for: When you need parallel processing
The Modern Standard
- Cleanest, most readable syntax
- Synchronous-looking asynchronous code
- Easy error handling with
try
/catch
- Best for: Most modern applications
Best of Both Worlds
- Modern syntax with parallel execution
- Combines readability of
async
/await
with speed ofPromise.all()
- Best for: High-performance applications
Each approach implements the same three-step process:
- Connect to Database - Simulated database connection
- Read Markdown File - Read and parse a markdown blog post
- Save to Database - Store the processed HTML in the database
- Simulates real database operations with timeouts
- Provides
connect()
andcreate()
methods - Includes error simulation capabilities
- Contains a simple markdown file for processing
- Demonstrates file system operations
- Callbacks: Error-first callback pattern
- Promises:
.catch()
method async
/await
:try
/catch
blocks
- Sequential: Operations run one after another
- Parallel: Operations run simultaneously (where possible)
- When to use each: Depends on data dependencies
- Callbacks: Can become nested and hard to read
- Promises: Better than callbacks, but can still chain
async
/await
: Most readable, looks like synchronous code
This is a learning repository! Feel free to:
- Add new async patterns
- Improve existing examples
- Add more comprehensive error handling
- Create additional practice exercises
MIT License - feel free to use this for educational purposes!
Remember: The best way to learn async programming is by doing. Run each example, modify the code, break things, and fix them. That's how you'll truly understand these concepts!