Node.js › Async Patterns

What is a callback function in Node.js, and what is 'callback hell'?

Beginner

Answer

A callback is a function passed as an argument to another function, invoked once that function's asynchronous work completes -- Node's original core APIs (fs, http, etc.) are all built around this 'error-first callback' convention. Callback hell refers to the deeply nested, hard-to-read pyramid of code that results from chaining multiple dependent asynchronous callback-based operations, one inside another, which promises and async/await were both introduced specifically to solve.
// Callback hell: deeply nested, hard to follow
fs.readFile('a.txt', (err, a) => {
  fs.readFile('b.txt', (err, b) => {
    fs.readFile('c.txt', (err, c) => {
      console.log(a, b, c);
    });
  });
});
Real-world example A legacy codebase with five levels of nested callbacks handling a user-registration flow (validate, hash password, save to database, send email, log event) is refactored to use async/await, immediately making the control flow readable top-to-bottom and making error handling consistent via a single try/catch.

Common follow-ups: What does 'error-first' mean in the error-first callback convention, and why was it adopted?;How would util.promisify() convert an existing callback-based function to return a promise instead?