改写Node.js中的回调为Promise

Posted by Yinode on Friday, November 24, 2017

TOC

传统的回调

首先让我们看一下在NODE中传统的异步读取文件

let fs = require("fs")


 fs.readFile("./justtest.html","utf-8",(err,data)=>{
 	console.log(data);
 })

//普通的回调方式处理异步

我们可以看到,读取文件之后的回调被添加到了参数之中。看起来好像没什么问题,但是当一旦回调机制变得复杂起来,就有可能产生回调地狱。

比如我们需要读取文件A,当文件A读取完毕读取文件B,B>c,c>d 当我们拥有一个很长的回调列表之后,整个代码就可能会复杂不堪,难以阅读。

fs.readFile("./fileA","utf-8",(err,data)=>{
	if(data){
		fs.readFile("./fileB","utf-8",(err,data)=>{
			if(data){
				fs.readFile("fileC","utf-8",(err,data)=>{
					if(data){
						// something
					}
				})
			}
		})
	}
})

你可以想象比这更复杂的代码该如何阅读

接下来就让我们用promie来解决这个问题

使用Promise改写

首先 我们需要一个可以吧普通函数Promise化的函数。

他接受一个需要被改造的函数,以及一个上下文对象

然后返回一个包装好的函数

function promiseify(fn,ctx){
	return function(...args){
		return new Promise((resolve,reject)=>{ //返回一个Promise对象

			let allArgs = args.concat(()=>(err,data)=>{
				if(err){reject(err)}
				if(data){resolve(data)}
})		//为参数添加普通回调函数 会触发相应的promise事件 也就是一个递交的过程
			fn.apply(ctx||this,allArgs) //调用目标函数,绑定上下文,传递参数数组
		})
	}
}

接下来的调用就非常方便了

let readFileInPromise = promiseify(fs.readFile,fs)

readFileInPromise("./justtest.html","utf-8").then((data)=>{
	console.log(data)
},(err)=>{
	console.log("发生错误:" + err)
})

你也可以在then的后面继续then以完成多重异步的过程。