Node.js6 min read

Understanding Callbacks in Node.js

Master callback patterns in Node.js. Understand error-first callbacks and avoid callback hell.

Sarah Chen
December 19, 2025
0.0k0

Understanding Callbacks in Node.js

Callbacks are functions passed as arguments. Node.js uses them everywhere.

What's a Callback?

```javascript function greet(name, callback) { const message = `Hello, ${name}!`; callback(message); }

greet('Alice', (msg) => { console.log(msg); // Hello, Alice! }); ```

Why Callbacks?

Node.js is non-blocking. Instead of waiting: ```javascript // Blocking (bad in Node.js) const data = readFileSync('file.txt'); // Waits here console.log(data);

// Non-blocking (good) readFile('file.txt', (err, data) => { console.log(data); // Runs when file is read }); console.log('This runs immediately!'); ```

Error-First Callbacks

Node.js convention: first argument is always error.

```javascript const fs = require('fs');

fs.readFile('file.txt', 'utf8', (err, data) => { if (err) { console.error('Error:', err.message); return; } console.log('Data:', data); }); ```

Creating Error-First Callbacks

```javascript function divide(a, b, callback) { if (b === 0) { callback(new Error('Cannot divide by zero')); return; } callback(null, a / b); }

divide(10, 2, (err, result) => { if (err) { console.error(err.message); return; } console.log('Result:', result); // 5 }); ```

Callback Hell (The Problem)

```javascript // Nested callbacks = hard to read fs.readFile('file1.txt', (err, data1) => { if (err) return handleError(err); fs.readFile('file2.txt', (err, data2) => { if (err) return handleError(err); fs.readFile('file3.txt', (err, data3) => { if (err) return handleError(err); // Finally do something with data1, data2, data3 console.log(data1, data2, data3); }); }); }); ```

Avoiding Callback Hell

**1. Named functions:** ```javascript function handleFile1(err, data1) { if (err) return handleError(err); fs.readFile('file2.txt', handleFile2); }

function handleFile2(err, data2) { if (err) return handleError(err); console.log('Done!'); }

fs.readFile('file1.txt', handleFile1); ```

**2. Use Promises (better):** ```javascript const fs = require('fs').promises;

async function readFiles() { const data1 = await fs.readFile('file1.txt'); const data2 = await fs.readFile('file2.txt'); const data3 = await fs.readFile('file3.txt'); return [data1, data2, data3]; } ```

Convert Callback to Promise

```javascript const { promisify } = require('util');

// Old callback style const readFile = promisify(fs.readFile);

// Now use with async/await const data = await readFile('file.txt', 'utf8'); ```

Key Takeaway

Callbacks are foundational in Node.js. Always handle errors first. Avoid deep nesting with named functions or better yet, use Promises and async/await for cleaner code.

#Node.js#Callbacks#Async#Beginner