fs模块中的方法都是异步请求,在for循环中使用fs函数时,for循环比较快,for循环结束后可能才会去异步请求,回调函数中的循环变量i是循环结束后的i的值。
demo.js:
var fs=require('fs'); //引入fs模块
//找出html目录下面的所有的目录,然后打印出来
//1. 错误写法 回调函数是异步。for循环比较快,for循环结束后才会去异步请求。
fs.readdir('html',function(error,files){
if(error){
console.log(error);
}else{ /*判断是目录还是文件夹*/
console.log(files); /*可以正常打印出数组*/
for(var i=0;i<files.length;i++){
console.log(files[i]); //可以正常打印出files[]
fs.stat("html/"+files[i],function(error,stats){ /* for循环判断是目录还是文件 ---异步 错误写法*/
if(stats.isDirectory()){
console.log(files[i]); //files[i] undefined (i超出下标) for循环比较快,for循环结束后才会去异步请求。此时i已经超出下标。
}
})
}
}
})
//打印出什么 3 3 3
//for(var i=0;i<3;i++){
// setTimeout(function(){ //异步,会出错。
// console.log(i); //打印出 3 3 3
// },100)
//}
//2. 正确的写法
var filesArr=[]; //存放目录的数组
fs.readdir('html',function(error,files){
if(error){
console.log(error);
}else{ /*判断是目录还是文件夹*/
//console.log(files); /*可以正常打印出数组*/
//正确写法,用可执行函数的递归 代替for循环
(function getFile(i){
if(i==files.length){ /*循环(递归)结束*/
console.log('目录:');
console.log(filesArr); /*打印出所有的目录*/
return false;
}
//files[i] = css js news.html
//注意:目录
fs.stat('html/'+files[i],function(error,stats){
if(stats.isDirectory()){ /*目录*/
filesArr.push (files[i]); /*保存数据*/
}
//递归掉用
getFile(i+1); //在异步回调函数里进行递归调用。依次异步请求,i依次加1,i就不会出错。
})
})(0) //(0)表示传递给getFile()函数的参数
}
})