nodejs中的readFile异步等待

readFile async await in nodejs

import http from "http"
import fs from "fs"

function readDemo(path){
    return new Promise((resolve,reject)=>{
        fs.readFile(path,(err,data)=>{
            if(err)
                reject(err);
            else
                resolve(data);
        })
    })
}

const server = http.createServer((req,res)=>{
    if(req.url === `/`){
        res.writeHead(200,{"Content-type":"text/html"});
        readDemo(`./todo.html`)//
            .then(data => res.write(data))
            .catch(console.log);
        res.end();
    }
})

server.listen(5000);

我正在尝试通过请求 localhost:5000 作为 运行 我自己的 Nodejs 服务器来加载 todo.html
似乎 fs.readFile 花了很长时间来加载 css 和 javascript 部分所以我做了 Promise 声明让 res.write 等待 fs.readFile 完成加载 todo.html 包括其中链接的 css 和 javascript。

但是代码集错误说

events.js:292
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at writeAfterEnd (_http_outgoing.js:668:15)
    at write_ (_http_outgoing.js:680:5)
    at ServerResponse.write (_http_outgoing.js:661:15)
    at file:///C:/Users/KUSW-14/Downloads/web_study-main/web_study-main/to_do_list/main.js:19:31   
Emitted 'error' event on ServerResponse instance at:
    at writeAfterEndNT (_http_outgoing.js:727:7)
    at processTicksAndRejections (internal/process/task_queues.js:81:21) {
  code: 'ERR_STREAM_WRITE_AFTER_END'
}  

任何人都可以帮我看看我的代码有什么问题吗?

readFile() 是非阻塞的,因此您在调用 res.write() 之前先调用 res.end()。我建议像这样使用 await

const server = http.createServer(async (req, res) => {
    if(req.url === `/`){
        try {
            const data = await readDemo(`./todo.html`);
            res.writeHead(200,{"Content-type":"text/html"});
            res.write(data)
            res.end();
        } catch(e) {
            console.log(e);
            res.writeHead(500);
            res.end();
        }
    } else {
        res.writeHead(404);
        res.end();
    }
});

没有await,你需要将res.end()移到.then():

里面
const server = http.createServer((req,res)=>{
    if(req.url === `/`){
        readDemo(`./todo.html`).then(data => {
            res.writeHead(200,{"Content-type":"text/html"});
            res.write(data);
            res.end();
        }).catch(err => {
            console.log(err);
            res.writeHead(500);
            res.end();
        });
    } else {
        res.writeHead(404);
        res.end();
    }
});

仅供参考,在 node.js 的现代版本中 fs.promises.readFile() 已经是一个 promise 版本,因此您不必自己制作。