面试题答案
一键面试fs
模块内部错误处理机制
- 回调函数方式:在
fs
模块的异步操作中,通常会将错误作为回调函数的第一个参数传递。例如,fs.readFile
的用法:
const fs = require('fs');
fs.readFile('nonexistentfile.txt', 'utf8', (err, data) => {
if (err) {
console.error('读取文件出错:', err);
return;
}
console.log('文件内容:', data);
});
当文件读取操作失败时(比如文件不存在),err
会被赋值为一个错误对象,包含错误的详细信息,开发者可以在回调函数中进行相应的错误处理。
- Promise方式:从Node.js v10开始,
fs
模块的很多方法都有了Promise版本(例如fs.promises.readFile
)。使用async/await
时,错误会通过try...catch
块来捕获。
const fs = require('fs').promises;
async function readMyFile() {
try {
const data = await fs.readFile('nonexistentfile.txt', 'utf8');
console.log('文件内容:', data);
} catch (err) {
console.error('读取文件出错:', err);
}
}
readMyFile();
在Promise链中,如果某个异步操作拒绝(reject),会抛出错误,被最近的catch
块捕获。
扩展fs
模块使其在特定错误时执行额外操作
- 封装现有方法:可以创建一个新的模块,封装
fs
模块的方法,并在封装的方法中添加额外的错误处理逻辑。
const fs = require('fs');
function myReadFile(filePath, encoding) {
return new Promise((resolve, reject) => {
fs.readFile(filePath, encoding, (err, data) => {
if (err) {
if (err.code === 'ENOENT') { // 特定错误,文件不存在
console.log('文件不存在,执行额外操作,比如创建文件');
// 这里可以添加创建文件的逻辑
}
reject(err);
} else {
resolve(data);
}
});
});
}
module.exports = {
myReadFile
};
然后在其他地方使用这个封装的方法:
const myFs = require('./myFsModule');
myFs.myReadFile('nonexistentfile.txt', 'utf8')
.then(data => console.log('文件内容:', data))
.catch(err => console.error('读取文件出错:', err));
- 使用Proxy(较新特性):可以使用ES6的Proxy来代理
fs
模块,拦截方法调用并添加错误处理逻辑。
const fs = require('fs');
const fsProxy = new Proxy(fs, {
get(target, prop) {
if (typeof target[prop] === 'function') {
return function (...args) {
const callback = args[args.length - 1];
if (typeof callback === 'function') {
args[args.length - 1] = function (err, ...results) {
if (err) {
if (err.code === 'ENOENT') {
console.log('文件不存在,执行额外操作,比如创建文件');
// 这里可以添加创建文件的逻辑
}
}
callback(err, ...results);
};
}
return Reflect.apply(target[prop], target, args);
};
}
return target[prop];
}
});
// 使用代理后的fs模块
fsProxy.readFile('nonexistentfile.txt', 'utf8', (err, data) => {
if (err) {
console.error('读取文件出错:', err);
} else {
console.log('文件内容:', data);
}
});
通过这种方式,在不改变原有fs
模块使用方式的前提下,为特定错误添加了额外的操作。