前面,我们简单的把功能实现了。实现了访问项目的资源文件。那么这里,我们进行一下代码优化,把代码中一些回调,用Promise 的方法重写一下。
下面是之前的代码:
const path = require('path');
const http = require('http');
const fs = require('fs');
const conf = require('./config/defaultConfig');
const server = http.createServer((req,res) => {
const url = req.url;
const filePath = path.join(conf.root, url);
fs.stat(filePath, (err,stats) => {
if (err) {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end(`${filePath} is not a file or directory`);
return;
}
if (stats.isFile()) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
fs.createReadStream(filePath).pipe(res)
}
if (stats.isDirectory()) {
fs.readdir(filePath, (err, files) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(files.join(", "));
})
}
})
});
server.listen(conf.port, conf.hostname, () => {
const addr = `http://${conf.hostname}:${conf.port}`;
console.log(`Server started at ${addr}`);
})
下面,是我们去掉回调函数,引用 util 库 下的 promisify 后的修改。如下。但是, 包含 await 的函数,必须是 async 的。因此我们在src 下新建一个目录 helper。
先修改一下app.js 代码如下。
const path = require('path');
const http = require('http');
const fs = require('fs');
const promisify = require('util').promisify;
const conf = require('./config/defaultConfig');
const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);
const server = http.createServer((req,res) => {
const url = req.url;
const filePath = path.join(conf.root, url);
try {
const stats = await stat(filePath);
if (stats.isFile()) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
fs.createReadStream(filePath).pipe(res)
}
if (stats.isDirectory()) {
fs.readdir(filePath, (err, files) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(files.join(", "));
})
}
} catch(ex) {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end(`${filePath} is not a file or directory`);
}
});
server.listen(conf.port, conf.hostname, () => {
const addr = `http://${conf.hostname}:${conf.port}`;
console.log(`Server started at ${addr}`);
})
然后,在 helper 下新建一个文件 route.js 。下面我们来写一下 route.js 如下(将await 部分代码放进来)。
const fs = require('fs');
const promisify = require('util').promisify;
const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);
module.exports = async function (req, res, filePath) {
try {
const stats = await stat(filePath);
if (stats.isFile()) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
fs.createReadStream(filePath).pipe(res)
}
if (stats.isDirectory()) {
fs.readdir(filePath, (err, files) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(files.join(", "));
})
}
} catch(ex) {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end(`${filePath} is not a file or directory`);
}
}
然后app.js 如下。
const path = require('path');
const http = require('http');
const conf = require('./config/defaultConfig');
const route = require('./helper/route');
const server = http.createServer((req,res) => {
const url = req.url;
const filePath = path.join(conf.root, url);
route(req, res, filePath);
});
server.listen(conf.port, conf.hostname, () => {
const addr = `http://${conf.hostname}:${conf.port}`;
console.log(`Server started at ${addr}`);
})
下面,我们把route.js 中fs.readdir 回调去掉,route.js 如下。
const fs = require('fs');
const promisify = require('util').promisify;
const stat = promisify(fs.stat);
const readdir = promisify(fs.readdir);
module.exports = async function (req, res, filePath) {
try {
const stats = await stat(filePath);
if (stats.isFile()) {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
fs.createReadStream(filePath).pipe(res)
}
if (stats.isDirectory()) {
const files = await readdir(filePath);
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(files.join(", "));
}
} catch(ex) {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
res.end(`${filePath} is not a file or directory`);
}
}