错误优先回调
【Error-first callbacks】
Node.js 核心 API 提供的大多数异步方法遵循一种习惯用法模式,称为“错误优先回调”。在这种模式下,一个回调函数作为参数传递给方法。当操作完成或发生错误时,回调函数会被调用,并且将 Error 对象(如果有的话)作为第一个参数传入。如果没有发生错误,第一个参数将传入 null。
【Most asynchronous methods exposed by the Node.js core API follow an idiomatic
pattern referred to as an error-first callback. With this pattern, a callback
function is passed to the method as an argument. When the operation either
completes or an error is raised, the callback function is called with the
Error object (if any) passed as the first argument. If no error was raised,
the first argument will be passed as null.】
const fs = require('node:fs');
function errorFirstCallback(err, data) {
if (err) {
console.error('There was an error', err);
return;
}
console.log(data);
}
fs.readFile('/some/file/that/does-not-exist', errorFirstCallback);
fs.readFile('/some/file/that/does-exist', errorFirstCallback); JavaScript 的 try…catch 机制不能用于拦截异步 API 产生的错误。初学者常犯的一个错误是尝试在错误优先的回调中使用 throw:
【The JavaScript try…catch mechanism cannot be used to intercept errors
generated by asynchronous APIs. A common mistake for beginners is to try to
use throw inside an error-first callback:】
// THIS WILL NOT WORK:
const fs = require('node:fs');
try {
fs.readFile('/some/file/that/does-not-exist', (err, data) => {
// Mistaken assumption: throwing here...
if (err) {
throw err;
}
});
} catch (err) {
// This will not catch the throw!
console.error(err);
} 这行不通,因为传给 fs.readFile() 的回调函数是异步调用的。在回调被调用时,外围代码,包括 try…catch 块,已经执行完毕。在回调内抛出错误在大多数情况下 可能会导致 Node.js 进程崩溃。如果启用了 域名,或者已经使用 process.on('uncaughtException') 注册了处理程序,这类错误是可以被拦截的。
【This will not work because the callback function passed to fs.readFile() is
called asynchronously. By the time the callback has been called, the
surrounding code, including the try…catch block, will have already exited.
Throwing an error inside the callback can crash the Node.js process in most
cases. If domains are enabled, or a handler has been registered with
process.on('uncaughtException'), such errors can be intercepted.】