将nodejs的fs模块异步
回调函数
风格转换为Promise
和await
风格。
nodejs的fs文件模块操作通常都有同步
和异步
两种实现方式,如读取文件操作:
一、同步模式
优点
- 同步读取文件代码风格较为符合人的常规习惯
缺点
- 不适用于服务中,因为同步读取文件的io操作会阻塞程序的执行,等到读取完成后才可以继续处理其他逻辑,当读取耗时较大的文件期间无法处理其他请求。
const fs = require('fs');
const data = fs.readFileSync('input.txt');
console.log("同步读取: " + data.toString());
二、异步 - 回调函数风格
优点
- 非阻塞式操作文件,在读取文件时不会影响其他请求的处理。
缺点
- 回调函数风格不太符合人的常规习惯,嵌套层次较深时容易产生
回调地狱
。
const fs = require('fs');
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取: " + data.toString());
});
三、异步 - Promise & await风格
优点
- 非阻塞式操作文件,在读取文件时不会影响其他请求的处理。
缺点
- 同步读取文件代码风格较为符合人的常规习惯。
const fs = require('./fs-async.js');// 此文件请见下一步中的代码
// promise风格
fs.readFile('input.txt').then(data => {
console.log("异步promise读取: " + data.toString());
}).catch(err => {
console.error(err);
});
// await风格,tip:要在async函数中方可使用await语法
const data = await fs.readFile('input.txt');
console.log("异步await读取: " + data.toString());
四、实现promise和await风格文件操作
原理:使用nodejs自带的util模块中的promisify方法,遍历fs模块的异步方法,将其变为promise风格
fs-async.js
const fs = require('fs');
const util = require('util');
/**
* 将nodejs的fs模块的异步操作变为promise模式
*/
function FsAsync(){
const prototype = this.constructor.prototype;
const isFun = (e) => Object.prototype.toString.call(e) === '[object Function]';
const isSync = (s) => s.indexOf('Sync') !== -1 || s.indexOf('sync') !== -1 ;
for(let p in fs){
const prop = fs[p];
if(isFun(prop)){
prototype[p] = isSync(prop.name) ? prop : util.promisify(prop);
}
}
}
module.exports = new FsAsync();