我一直在努力解决这个问题已经有一个星期了,我已经阅读了几十篇关于回调的文章和帖子,其中一些一遍又一遍。我仍然不明白 - 至少我正在努力做什么。
function rFile(dIn, callback){ // 4.
fs.readFile(dIn,function(err,dOut){
if(!err){
console.log('rFile OUT: '+dOut+' B Size: '+dOut.length);
} else {
console.log('rFile ERR: '+err);
};
callback(dOut);
});
}
function getRtn(dOut){ // 3.
console.log('getRtn OUT: '+dOut);
rtn = dOut;
return dOut;
};
function sendPage() { // 2.
rFile('index.htm', getRtn);
console.log('sendPage OUT: '+rtn);
rFile('404.htm', getRtn);
console.log('sendPage OUT: '+rtn);
}
function requestHandler(req, res) { // 1.
sendPage();
res.end();
console.log('sendPage OUT: '+rtn);
}
http.createServer(requestHandler).listen(3000);
我在getRtn()中有来自fs.readfile的结果,但我无法设计一个回调方案来将相同的结果输入到sendPage()中,并可能返回到requestHandler()。
sendPage()会做很多事情,但它会成为许多不同事物的集合点。
我已经尝试了25次将回调插入到getRtn()中,但是它出现“意外功能”错误,即使没有错误,我也不知道......我只是不知道。即使在fs.read中运行的一个回调中,我也不知道是谁在调用谁。
但最后,sendpage将收集来自十几个不同函数的所有结果,其中一些函数可能来自几个函数,因此结果将通过许多函数遍历许多回调。
如果有人能告诉我如何继续从我在getRtn中看到的结果回调,一直回到requestHandler()(或者至少回到sendPage(),我将永远感激。
答案 0 :(得分:1)
function rFile(callback) {
console.log('rFile called');
callback('rFile');
}
function getRtn(callback) {
console.log('getRtn called');
callback('Returned data!');
}
function sendPage() {
rFile(function (rFile) {
getRtn(function (data) {
console.log(rFile, data);
// do what you like with the data here.
});
});
}
sendPage(); // console: 'rFile called', 'getRtn called', 'rFile', 'Returned data!'
答案 1 :(得分:0)
我认为你不需要这么多层功能......用匿名函数完成,代码可能看起来像这样......
var http = require('http');
var fs = require('fs');
function requestHandler(req, res) {
console.log('Request received: '+req.url);
res.setHeader("Content-Type", "text/html");
fs.readFile("index.htm", function(err, data ) {
if (err) throw err;
console.log('sending page out:\n' + data);
res.end(data);
});
}
http.createServer(requestHandler).listen(3000);
每次回调实际上只是等待某事发生。它只是让节点在等待时执行summat else ...一个问题是与作用域有关... res需要在readfile回调的范围内才能写入它。我编写它的方式会创建一个闭包,因此回调仍然可以访问外部作用域中的变量。如果你想分离这些函数,你必须在requestHander中定义回调 以获得正确的闭包:
function requestHandler(req, res) {
function rfCallback(err, data ){
if (err) {console.log('Readfile Err');throw err;}
res.end(data);
console.log('sendPage OUT:\n'+ data);
}
console.log('Request received: '+req.url);
res.setHeader("Content-Type", "text/html");
fs.readFile("index.htm", rfCallback); //set up the read & send
}
我认为第一种方式更具可读性。 : - )
它的工作方式是:
请求进入并调用其回调。
该回调(requestHandler
)设置了读取并移交其回调...
...一旦提取了文件就会启动,并完成发送响应的处理。
所以,这是一个普遍的答案。但在这种情况下,有一种更简单的方法,使用.pipe()
:
var http = require('http');
var fs = require('fs');
function requestHandler(req, res) {
console.log('Request received: '+req.url);
res.setHeader("Content-Type", "text/html");
fs.createReadStream("index.htm").pipe(res); //set up the read & send
}
http.createServer(requestHandler).listen(3000);