错误优先回调
¥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.