node.js将异步的遍历文件目录改成同步

我们都知道,如果想读取某一目录下的文件时,需使用fs.readdir来进行,看如下代码:

function getFileList(filePath){
	fs.readdir(filePath, (err, files)=> {
	    var listArr = [];
		files.forEach(filename => {
			listArr.push(filename);
		})
		return listArr;
	})
}
const filePath = path.resolve(path.join(__dirname, '../public/images'));
getFileList(filePath)   //undefined

我们可以看到,此时打印出的是undeifined,很明显,在异步操作readdir执行完之前,函数已经走完了,所以是个undeifined。我们再看一个例子:

function getFileList(filePath) {
    var listArr = [];
    fs.readdir(filePath, (err, files) => {
        files.forEach(filename => {
            listArr.push(filename);
        })
    })
    return listArr   
}
const filePath = path.resolve(path.join(__dirname, '../public/images'));
getFileList(filePath)  // []

这个例子就很鲜明的体现了异步调用里的坑,那么我们如何处理这个问题呢?有以下方案可供选择:

1.经典的callback回调思路

const fs = require('fs');
const path = require('path');
const util = require('util');

/*1.通过将匿名函数作为参数将result传出 */
function getFileList(dir, callback) {
    fs.readdir(dir, (err, files) => {
        if (err) {
            callback(err);
            return;
        }
        var listArr = [];
        if (files && files.length) {
            files.forEach(filename => {
                listArr.push(filename);
            });
        }
        callback(null, listArr)
    })
}

const filePath = path.resolve(path.join(__dirname, '../public/images'));
getFileList(filePath, (err, data) => {
    console.log('data', data)
})

2.Promise包裹方案

const fs = require('fs');
const path = require('path');
const util = require('util');

/**2.通过promise,本质上还是通过一个函数将参数带出来,唯一区别在于它返回的东西是一个promise对象,需要通过then才能拿到data */
function getFileList(filePath) { 
    return new Promise((resovle, reject) => {
        fs.readdir(filePath, (err, files) => {
            var listArr = [];
            files.forEach(filename => {
                listArr.push(filename);
                resovle(listArr);
            }) 
        })
    })
 }
 const filePath = path.resolve(path.join(__dirname, '../public/images'));
 getFileList(filePath).then(data => {
     console.log('data', data)
 })

3.async和await改写

const fs = require('fs');
const path = require('path');
const util = require('util');

/**3.使用async和await改写,本质也是通过promise来传递参数 */
async function getFileList(filePath) { 
    try{
        var readdir = util.promisify(fs.readdir);
        let files = await readdir(filePath);
        var listArr = [];
        if(files && files.length){
            files.forEach(filename => {
                listArr.push(filename);
            });
        }
        return listArr;
    }catch(err){
        console.log(err)
    }

 }
 const filePath = path.resolve(path.join(__dirname, '../public/images'));
 getFileList(filePath).then(data => {
     console.log('data', data)
 })

4.通过同步的fs.readdirSync来替换

function getFileList(filePath) {
    var files = fs.readdirSync(filePath);
    var listArr = [];
    files.forEach(filename => {
        listArr.push(filename);
    })
   }
const filePath = path.resolve(path.join(__dirname, '../public/images'));
getFileList(filePath);

至此,异步方案已经全部放出,应该都可以满足各位的需求。有问题的话需要交流的话,欢迎在底部给我留言。

你可能感兴趣的:(ES6,node.js)