如何将使用 fs.readFileSync() 的 Node.js 代码重构为使用 fs.readFile()?
Posted
技术标签:
【中文标题】如何将使用 fs.readFileSync() 的 Node.js 代码重构为使用 fs.readFile()?【英文标题】:How to refactor Node.js code that uses fs.readFileSync() into using fs.readFile()? 【发布时间】:2014-05-16 18:56:15 【问题描述】:我试图了解 Node.js 中的同步与异步,尤其是在读取 html 文件时。
在请求处理程序中,我正在使用的同步版本如下:
var fs = require("fs");
var filename = "./index.html";
var buf = fs.readFileSync(filename, "utf8");
function start(resp)
resp.writeHead(200, "Content-type": "text/html" );
resp.write(buf);
resp.end();
exports.start = start;
-
使用
readFile()
的版本是什么?
我知道readFile
是异步的,所以理论上我应该等待整个文件被读取后再渲染,所以我应该引入addListener
吗?我可能会混淆不同的东西。
编辑:我曾尝试像这样重构代码:
var fs = require("fs");
var filename = "./index.html";
function start (resp)
resp.writeHead(200, "Content-Type": "text/html" );
fs.readFile(filename, "utf8", function (err, data)
if (err) throw err;
resp.write(data);
);
resp.end();
我得到一个空白页。我猜是因为它应该等待读取所有数据,在resp.write(data)
之前,我该如何发出这个信号?
【问题讨论】:
您是否在问,如果您要使用readFile()
,等效代码是什么?您将如何处理异步发送内容?
@AnthonyForloney 是的,这就是我要问的,使用 fs.readFile() 的等效代码是什么?
在您的回调中移动resp.end()
。这就是你得到一个空白页的原因。
@AnthonyForloney 是的,我在 lombausch 的回答中看到了这一点,你知道为什么我需要将 resp.end() 放在回调中吗?谢谢
当你在上面的代码中使用异步方法时,比如readFile
,你告诉程序“读取文件的内容,当你完成时(关键字,'when')读取内容,将它们用作响应主体”。如果在回调中不提供resp.end()
调用(如上所示),程序会调用readFile
,然后在你的回调有时间执行resp.write
之前立即调用resp.end()
。这有意义吗?
【参考方案1】:
var fs = require("fs");
var filename = "./index.html";
function start(resp)
resp.writeHead(200,
"Content-Type": "text/html"
);
fs.readFile(filename, "utf8", function(err, data)
if (err) throw err;
resp.write(data);
resp.end();
);
【讨论】:
谢谢,它确实有效。后续问题,您可能已经看到我的编辑,在我的暂定答案中,我没有在回调中包含 resp.end(),这不起作用,您知道为什么它必须在回调中吗? Rgds 如果您不在回调中提供它,您的resp.end()
将立即被调用,因为它不等待回调的响应。【参考方案2】:
这个变种更好,因为你不知道文件是否存在。当您确定可以读取文件内容时,您应该发送正确的标题。此外,如果您有没有以 '.end()' 结尾的代码分支,浏览器将等到它得到它们。也就是说,您的浏览器会等待很长时间。
var fs = require("fs");
var filename = "./index.html";
function start(resp)
fs.readFile(filename, "utf8", function(err, data)
if (err)
// may be filename does not exists?
resp.writeHead(404,
'Content-Type' : 'text/html'
);
// log this error into browser
resp.write(err.toString());
resp.end();
else
resp.writeHead(200,
"Content-Type": "text/html"
);
resp.write(data.toString());
resp.end();
);
【讨论】:
以上是关于如何将使用 fs.readFileSync() 的 Node.js 代码重构为使用 fs.readFile()?的主要内容,如果未能解决你的问题,请参考以下文章
fs.readFileSync无法读取nodejs中的文件传递路径变量
使用 lambda 部署时 fs.readFileSync 找不到文件
fs.readFileSync 不是 Meteor 的函数,React