node.js將非同步的讀取檔案目錄改成同步
阿新 • • 發佈:2018-12-21
我們都知道,如果想讀取某一目錄下的檔案時,需使用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);
至此,非同步方案已經全部放出,應該都可以滿足各位的需求。有問題的話需要交流的話,歡迎在底部給我留言。