1. 程式人生 > >node.js將非同步的讀取檔案目錄改成同步

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

至此,非同步方案已經全部放出,應該都可以滿足各位的需求。有問題的話需要交流的話,歡迎在底部給我留言。