错误优先回调要求回调函数首参数为err,必须检查其存在性并立即处理;err应为Error实例,成功时传null;避免在回调内抛异常,需与Promise兼容转换。

在JavaScript异步操作中,错误优先回调(Error-First Callback)是一种约定俗成的函数参数顺序规范:回调函数的第一个参数始终是错误对象(err),后续参数才是成功时的数据。遵守这一规范,能让错误处理更统一、可预测,也便于与Node.js原生API及大量第三方库协同工作。
回调函数必须检查 err 参数
调用错误优先回调后,第一件事就是判断 err 是否为真值。只要 err 存在(非 null、非 undefined),就应立即处理错误,**不执行后续逻辑**。
- 常见写法:
if (err) return callback(err);或if (err) throw err;(仅限同步上下文) - 错误未检查会导致“静默失败”——程序继续运行但数据异常,排查困难
- 即使你打算忽略某个错误,也应显式注释原因,例如:
// 忽略 ENOENT,文件不存在视为正常
err 应为 Error 实例或 null/undefined
传递给回调的错误参数应尽量是 Error 对象(如 new Error('xxx') 或 new TypeError()),而非字符串、数字等原始值。
- 理由:Error 实例自带
stack、message、name等属性,利于调试和分类处理 - 避免:
callback('file not found');→ 应改为callback(new Error('file not found')); - 成功时务必传
null或undefined,不可省略第一个参数,否则调用方无法区分“出错”和“没传 err”
避免在回调中抛出未捕获异常
错误优先回调本身是异步入口,其内部若抛出异常,将脱离当前执行栈,可能触发全局 uncaughtException,导致进程意外退出。
- 正确做法:把错误通过回调传出,由上层决定如何处理(记录、重试、响应用户等)
- 反例:
fs.readFile('x.txt', (err, data) => { if (err) throw err; console.log(data.toUpperCase()); });—— 若data是null,toUpperCase()报错将无法被该回调捕获 - 建议:对回调内的同步操作也做防御性检查,例如
if (data && typeof data === 'string') {...}
与 Promise 和 async/await 兼容时注意转换逻辑
现代代码常混合使用回调与 Promise,转换时需严格保持错误优先语义。
- 封装回调 API 为 Promise 时:
resolve对应成功数据,reject对应err(且只 reject Error 实例) - 反向转换(Promise → 回调)时,
.then(...).catch(err => callback(err)),确保err是 Error 实例,不要传undefined或空对象 - 使用
util.promisify时,目标函数必须严格遵循错误优先格式,否则 promisified 后的行为不可靠
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











