nodejs的fs模块回调函数风格的异步操作转化为promise和await风格

1,706 阅读2分钟

将nodejs的fs模块异步回调函数风格转换为Promiseawait风格。

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();