ant*_*zio 3 asynchronous fs node.js express es6-promise
在此Expressjs路由文件中,我尝试(递归地)获取./data目录内的所有 JSON 文件。
实际上,我可以在此处console.log文件,您可以看到A Mark,但我找不到在异步内容完成后将整组路径发送到视图的方法。
一些帮助将非常感激。
这是数据./数据结构:
--- dir1
`-- json1.json
`-- json2.json
--- dir2
`-- json3.json
--- dir3
Run Code Online (Sandbox Code Playgroud)
const express = require('express'),
router = express.Router(),
fs = require('fs'),
path = require('path')
;
let scan = function (directoryName = './data') {
return new Promise((resolve, reject) => {
fs.readdir(directoryName, function (err, files) {
if (err) reject(err);
files.map((currentValue, index, arr) => {
let fullPath = path.join(directoryName, currentValue);
fs.stat(fullPath, function (err, stat) {
if (err) reject(err);
if (stat.isDirectory()) {
scan(fullPath);
} else {
console.log(currentValue); <= (A mark)
//resolve();
}
});
});
});
})
};
router.get('/', (req, res, next) => {
scan()
.then(data => res.render('list', {
title: 'List',
data: data
}))
.catch(next);
});
module.exports = router;
Run Code Online (Sandbox Code Playgroud)
fs如果您承诺正在使用的函数,以便所有异步逻辑都是承诺,然后使用 async/await 来帮助您序列化控制流,则可以大大简化任务。
这是一种方法:
const promisify = require('util').promisify;
const path = require('path');
const fs = require('fs');
const readdirp = promisify(fs.readdir);
const statp = promisify(fs.stat);
async function scan(directoryName = './data', results = []) {
let files = await readdirp(directoryName);
for (let f of files) {
let fullPath = path.join(directoryName, f);
let stat = await statp(fullPath);
if (stat.isDirectory()) {
await scan(fullPath, results);
} else {
results.push(fullPath);
}
}
return results;
}
Run Code Online (Sandbox Code Playgroud)
以上代码在node v10.14.1中测试。
然后您可以像以前一样使用它:
router.get('/', (req, res, next) => {
scan().then(data => res.render('list', {
title: 'List',
data: data
})).catch(next);
});
Run Code Online (Sandbox Code Playgroud)
仅供参考,该模块有一个更新的(仍是实验性的)基于承诺的 API fs。你可以像这样使用它:
const path = require('path');
const fsp = require('fs').promises;
async function scan2(directoryName = './data', results = []) {
let files = await fsp.readdir(directoryName, {withFileTypes: true});
for (let f of files) {
let fullPath = path.join(directoryName, f.name);
if (f.isDirectory()) {
await scan2(fullPath, results);
} else {
results.push(fullPath);
}
}
return results;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这个新版本还使用了新withFileTypes选项,无需调用stat()每个文件。