Node.js创建服务器时fs.readFileSync失效问题及异步概念咨询
代码问题修复与概念解释
你的代码核心问题
- 同步方法误用回调:
fs.readFileSync是同步读取方法,它直接返回文件内容(或抛出错误),不接受回调函数,你写的回调永远不会执行,这是最关键的错误。 - 未处理POST请求体:Node.js的
req对象不会自动解析请求体,需要手动监听data和end事件来收集POST数据,req.body不会凭空出现。 - 文件名不一致:读取的是
chat.txt,写入的却是chats.txt,导致读写的不是同一个文件。 - 同步方法阻塞服务器:
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
相关产品推荐
相关产品推荐

