Node.js 写一个简单的静态服务器 3 使用Promise 优化代码

本文介绍如何通过Promise和async/await语法优化Node.js服务器代码,实现更简洁、易读的异步文件处理流程,包括文件和目录的访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面,我们简单的把功能实现了。实现了访问项目的资源文件。那么这里,我们进行一下代码优化,把代码中一些回调,用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`);
      }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值