详解ES6 系列之异步处理实战
前言
我们以查找指定目录下的最大文件为例,感受从
回调函数->Promise->Generator->Async
异步处理方式的改变。
API介绍
为了实现这个功能,我们需要用到几个Nodejs的API,所以我们来简单介绍一下。
fs.readdir
readdir方法用于读取目录,返回一个包含文件和目录的数组。
fs.stat
stat方法的参数是一个文件或目录,它产生一个对象,该对象包含了该文件或目录的具体信息。此外,该对象还有一个isFile()方法可以判断正在处理的到底是一个文件,还是一个目录。
思路分析
我们基本的实现思路就是:
- 用fs.readdir获取指定目录的内容信息
- 循环遍历内容信息,使用fs.stat获取该文件或者目录的具体信息
- 将具体信息储存起来
- 当全部储存起来后,筛选其中的是文件的信息
- 遍历比较,找出最大文件
- 获取并返回最大文件
然后我们直接上代码吧。
回调函数
varfs=require('fs');
varpath=require('path');
functionfindLargest(dir,cb){
//读取目录下的所有文件
fs.readdir(dir,function(er,files){
if(er)returncb(er);
varcounter=files.length;
varerrored=false;
varstats=[];
files.forEach(function(file,index){
//读取文件信息
fs.stat(path.join(dir,file),function(er,stat){
if(errored)return;
if(er){
errored=true;
returncb(er);
}
stats[index]=stat;
//事先算好有多少个文件,读完1个文件信息,计数减1,当为0时,说明读取完毕,此时执行最终的比较操作
if(--counter==0){
varlargest=stats
.filter(function(stat){returnstat.isFile()})
.reduce(function(prev,next){
if(prev.size>next.size)returnprev
returnnext
})
cb(null,files[stats.indexOf(largest)])
}
})
})
})
}
使用方式为:
//查找当前目录最大的文件
findLargest('./',function(er,filename){
if(er)returnconsole.error(er)
console.log('largestfilewas:',filename)
});
Promise
varfs=require('fs');
varpath=require('path');
varreadDir=function(dir){
returnnewPromise(function(resolve,reject){
fs.readdir(dir,function(err,files){
if(err)reject(err);
resolve(files)
})
})
}
varstat=function(path){
returnnewPromise(function(resolve,reject){
fs.stat(path,function(err,stat){
if(err)reject(err)
resolve(stat)
})
})
}
functionfindLargest(dir){
returnreadDir(dir)
.then(function(files){
letpromises=files.map(file=>stat(path.join(dir,file)))
returnPromise.all(promises).then(function(stats){
return{stats,files}
})
})
.then(data=>{
letlargest=data.stats
.filter(function(stat){returnstat.isFile()})
.reduce((prev,next)=>{
if(prev.size>next.size)returnprev
returnnext
})
returndata.files[data.stats.indexOf(largest)]
})
}
使用方式为:
findLargest('./')
.then(function(filename){
console.log('largestfilewas:',filename);
})
.catch(function(){
console.log(error);
});
Generator
varfs=require('fs');
varpath=require('path');
varco=require('co')
varreadDir=function(dir){
returnnewPromise(function(resolve,reject){
fs.readdir(dir,function(err,files){
if(err)reject(err);
resolve(files)
})
})
}
varstat=function(path){
returnnewPromise(function(resolve,reject){
fs.stat(path,function(err,stat){
if(err)reject(err)
resolve(stat)
})
})
}
function*findLargest(dir){
varfiles=yieldreadDir(dir);
varstats=yieldfiles.map(function(file){
returnstat(path.join(dir,file))
})
letlargest=stats
.filter(function(stat){returnstat.isFile()})
.reduce((prev,next)=>{
if(prev.size>next.size)returnprev
returnnext
})
returnfiles[stats.indexOf(largest)]
}
使用方式为:
co(findLargest,'./')
.then(function(filename){
console.log('largestfilewas:',filename);
})
.catch(function(){
console.log(error);
});
Async
varfs=require('fs');
varpath=require('path');
varreadDir=function(dir){
returnnewPromise(function(resolve,reject){
fs.readdir(dir,function(err,files){
if(err)reject(err);
resolve(files)
})
})
}
varstat=function(path){
returnnewPromise(function(resolve,reject){
fs.stat(path,function(err,stat){
if(err)reject(err)
resolve(stat)
})
})
}
asyncfunctionfindLargest(dir){
varfiles=awaitreadDir(dir);
letpromises=files.map(file=>stat(path.join(dir,file)))
varstats=awaitPromise.all(promises)
letlargest=stats
.filter(function(stat){returnstat.isFile()})
.reduce((prev,next)=>{
if(prev.size>next.size)returnprev
returnnext
})
returnfiles[stats.indexOf(largest)]
}
使用方式为:
findLargest('./')
.then(function(filename){
console.log('largestfilewas:',filename);
})
.catch(function(){
console.log(error);
});
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。