You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js创建服务器时fs.readFileSync失效问题及异步概念咨询

代码问题修复与概念解释

你的代码核心问题

  1. 同步方法误用回调:fs.readFileSync是同步读取方法,它直接返回文件内容(或抛出错误),不接受回调函数,你写的回调永远不会执行,这是最关键的错误。
  2. 未处理POST请求体:Node.js的req对象不会自动解析请求体,需要手动监听data和end事件来收集POST数据,req.body不会凭空出现。
  3. 文件名不一致:读取的是chat.txt,写入的却是chats.txt,导致读写的不是同一个文件。
  4. 同步方法阻塞服务器:readFileSync和writeFileSync会阻塞整个服务器进程,处理请求时其他请求会被挂起,生产环境绝不推荐。

修正后的代码(使用异步+Promise+async/await,更清晰高效)

const http = require('http');
const fs = require('fs').promises; // 使用Promise版本的fs模块
const path = require('path');

const chatFilePath = path.join(__dirname, 'chat.txt');

const server = http.createServer(async (req, res) => {
  console.log(`Received request: ${req.method}`);
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');

  try {
    if (req.method === 'GET') {
      // GET请求:读取chat.txt并返回
      const data = await fs.readFile(chatFilePath, 'utf8');
      res.end(data);
    } else if (req.method === 'POST') {
      // POST请求:收集请求体,更新文件
      let body = '';
      req.on('data', chunk => {
        body += chunk.toString('utf8');
      });
      req.on('end', async () => {
        try {
          let chats = [];
          try {
            // 尝试读取现有文件,文件不存在则初始化空数组
            const existingData = await fs.readFile(chatFilePath, 'utf8');
            chats = existingData.split('\n').filter(line => line.trim()); // 过滤空行
          } catch (err) {
            if (err.code !== 'ENOENT') throw err; // 只有文件不存在时忽略错误
          }

          // 限制最多40条记录
          if (chats.length >= 40) {
            chats.shift();
          }
          chats.push(body.trim());

          // 写入文件,用换行符拼接
          await fs.writeFile(chatFilePath, chats.join('\n'));
          res.end('Message saved');
        } catch (err) {
          res.statusCode = 500;
          res.end(`Error: ${err.message}`);
        }
      });
    } else {
      res.statusCode = 405;
      res.end('Method not allowed');
    }
  } catch (err) {
    res.statusCode = 500;
    res.end(`Error: ${err.message}`);
  }
});

server.listen(8080, () => {
  console.log('Server running on http://localhost:8080');
});

极简概念解释

  • Promises:用来封装异步操作的对象,代表一个“未来才会有结果”的任务。它有三种状态:等待中、成功、失败,通过then()处理成功结果,catch()处理失败原因,避免嵌套回调的混乱。
  • async/await:基于Promise的语法糖。async修饰的函数会自动返回Promise;await只能在async函数里用,它会暂停函数执行,直到对应的Promise完成,让异步代码看起来和同步代码一样线性、易读。

内容的提问来源于stack exchange,提问作者AlirezaBest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:07:29