历史背景

Node 早期所有异步都用回调:

const fs = require('fs');

fs.readFile('config.json', 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(data);
});

"Error-first" 约定(Node 风格)

function asyncOp(arg, callback) {
    // 完成后调用 callback(err, result)
    if (somethingWrong) {
        return callback(new Error('Failed'));    // ★ 第一个参数永远是 error
    }
    callback(null, result);                       // 成功时 err 是 null
}

调用方:

asyncOp(arg, (err, result) => {
    if (err) {
        console.error(err);
        return;
    }
    // 用 result
});

Callback Hell

嵌套深 → 难读、难错误处理:

fs.readFile('a.json', (err, dataA) => {
    if (err) return console.error(err);
    fs.readFile('b.json', (err, dataB) => {
        if (err) return console.error(err);
        fs.writeFile('out.json', dataA + dataB, (err) => {
            if (err) return console.error(err);
            console.log('Done');
        });
    });
});

这是经典"末日金字塔"——也是 Promise 诞生的原因。

现代用法:基本不直接写回调了

// 老式回调
fs.readFile('a.json', 'utf8', (err, data) => { ... });

// 现代 Promise(推荐)
import { readFile } from 'fs/promises';
const data = await readFile('a.json', 'utf8');

把回调 API 转 Promise

import { promisify } from 'util';
import fs from 'fs';

const readFile = promisify(fs.readFile);
const data = await readFile('a.json', 'utf8');

或自己包:

function readFilePromise(path) {
    return new Promise((resolve, reject) => {
        fs.readFile(path, 'utf8', (err, data) => {
            if (err) reject(err);
            else resolve(data);
        });
    });
}

EventEmitter 模式(另一种"回调")

import { EventEmitter } from 'events';

const ee = new EventEmitter();
ee.on('data', chunk => console.log('Got:', chunk));
ee.emit('data', 'hello');

详见 20-events。

何时还需要懂回调

  • 维护老项目
  • 看 Node 早期文档
  • 一些库(如 http.createServer((req, res) => ...))仍是回调风格
  • Stream / EventEmitter 是回调演化

新代码几乎不直接写 Node 风格回调——promisify / async-await 已经全面取代。

  • 调 callback 后别忘 return——不然代码继续往下跑
  • 同一个 callback 被调多次——bug 来源(Promise 不会)
  • 嵌套深时 try-catch 不能跨回调——错误必须在每层手动传

下一篇:Promise。