以下代码将启动一个服务器,该服务器在命中时(片段1)不响应。 Nodejs不执行回调函数,也不引发任何错误
const http = require('http');
var port=3000;
var http_server = http.createServer(server_callback);
http_server.listen(port, ()=>{
console.log("HTTP server is listening on port", port);
});
var server_callback = (req,res)=>{
res.end("hello\n");
}
但这可行(代码段2)
const http = require('http');
var port=3000;
var server_callback = (req,res)=>{
res.end("hello\n");
}
var http_server = http.createServer(server_callback);
http_server.listen(port, ()=>{
console.log("HTTP server is listening on port", port);
});
这也是(片段3)
const http = require('http');
var port=3000;
var http_server = http.createServer(function(req,res){
server_callback(req,res)
});
http_server.listen(port, ()=>{
console.log("HTTP server is listening on port", port);
});
var server_callback = (req,res)=>{
res.end("hello\n");
}
因此,我可以想出为什么片段2和片段1不能工作的一个解释是创建服务器时片段1中没有定义server_callback。 但这并不能解释为什么它可以在代码段3中使用。
这是怎么回事? 以及为什么从片段1中命中服务器时节点不会引发任何错误
答案 0 :(得分:4)
传递到.createServer
的参数在调用.createServer
时立即存储在内部。然后,在对服务器执行ping操作时,将调用该参数(希望是函数)。在摘要1中,您的
var http_server = http.createServer(server_callback);
解析为
var http_server = http.createServer(undefined);
因此createServer
的内部没有存储的函数供以后调用。
在代码段2中,传递的值是实函数:server_callback
已分配给它,因此解析为
var http_server = http.createServer((req,res)=>{
res.end("hello\n");
});
所以.createServer
确实具有内部存储的功能,以后可以调用。同样,在代码段3中,您传递了一个可以调用的函数:
var http_server = http.createServer(function(req,res){
server_callback(req,res)
});
在这里,不必在传递回调时定义server_callback
,但在脚本完成并且服务器正在等待连接时,最后一行该脚本将运行,并分配给server_callback
,因此它将成功运行。
实际上,这实际上与Node没有任何关系-您将看到任何基于回调的函数都具有相同的行为。等效代码段1:
// similar to createServer:
const createSomething = callback => {
setTimeout(callback, 500);
};
createSomething(server_callback);
var server_callback = () => console.log('callback running');
等效代码段2:
// similar to createServer:
const createSomething = callback => {
setTimeout(callback, 500);
};
var server_callback = () => console.log('callback running');
createSomething(server_callback);
等效代码段3:
// similar to createServer:
const createSomething = callback => {
setTimeout(callback, 500);
};
createSomething(() => server_callback());
var server_callback = () => console.log('callback running');
答案 1 :(得分:2)
此现象是由于javascript中的功能提升引起的。使用function
关键字声明函数时,该函数被解析为好像位于文件或外部函数的最顶部。但是,它很大,但是当将一个函数声明为一个函数表达式时,吊装将不起作用。
像这样:
function name(){}
吊起,并且在内存中可以进行其他操作,
var name = function(){}
没有。
编辑:正如SomePerformance在注释中指出的那样,您的每个函数都被声明为一个表达式。如果您使用函数关键字声明回调,第一个示例将正常工作
function server_callback(req,res){
res.end("hello\n");
}