Javascript 节点JS匿名函数和回调
有人请帮帮我。我一直在阅读大量javascript文档,并在处理javascript 我能够使用这些函数,但我不太理解这里的基本语法爵士乐Javascript 节点JS匿名函数和回调,javascript,node.js,http,callback,Javascript,Node.js,Http,Callback,有人请帮帮我。我一直在阅读大量javascript文档,并在处理javascript 我能够使用这些函数,但我不太理解这里的基本语法爵士乐 var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.en
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, 'myhost');
console.log('Server running at http://myhost:1337/');
我不明白为什么可以在上面的匿名函数中使用req和res。就像他们生活在http的某个地方。它们没有在任何地方申报!它们由引用内部对象或其他内容的匿名函数中的变量名组成。这太疯狂了
这样的回调函数是如何实现的
或者
stream.on('data', function(data){
// use data... i dont know where its coming from
// or how it got there, but use it
});
如果您可以发布一个模拟这个过程和语法的小示例,或者解释这些回调函数如何像这样工作,或者我如何将这些未声明的变量传递到像这样的函数中,我将不胜感激
下面是一个与答案类似的例子
var b = {
somefunction : function( data ){
var x = 100;
x = x+1; // 101
return data(x); // returns the callback function data w/ value x
}
};
b.somefunction(function(foo){
foo++; // 101 + 1
console.log(foo); // prints 102
});
您应该使用文档。 例如,对于createServer,请遵循以下页面- http.createServer([requestListener])#返回一个新的web服务器对象 requestListener是一个自动添加到 “请求”事件 然后,检查“请求”事件- 事件:'request'#函数(请求,响应){} 每次有请求时发出。请注意,可能有多个 每个连接的请求数(在保持活动连接的情况下)。 请求是http.IncomingMessage的实例,响应是 http.ServerResponse的实例 关于溪流,完全相同。这里的文件- 寻找 事件:“数据”
req和res实际上是匿名函数的局部变量。
下面我举了一个与你问题中的代码类似的例子
// static class
var HelperClass = {
"doSomething" : function ( callback ) {
// do something here, for example ajax call to a server
var data = ajaxCallFromServer();
// return the data via callback
callback ( data );
};
};
// you codes here calling the HelperClass
// calling .doSomething method with an anonymous function callback
// that expects 1 parameter. This parameter is returned by the above
// code via callback ( data ). And in the anonymous function
// i called it as retData, you can call it whatever you like
HelperClass.doSomething( function ( retData ) {
// do soemthing with your retData here
});
关键是
http.createServer
函数接受的参数不是变量,而是函数(如果有意义的话)。在javascript中,您可以做到这一点。该函数需要在其API中指定的参数。您可以将其设置为匿名,如示例中所示,或声明如下:
function serverFunction(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}
var http = require('http');
http.createServer(serverFunction).listen(1337, 'myhost');
但最终这并不重要,它只是根据API中指定的内容进行操作 主要问题是Javascript是一种函数式语言,因此您可以将函数作为参数传递给其他函数。例如,在其他语言中,您可能经历过向函数传递指针或句柄。考虑一个简单的例子,其中你有一些数学函数:
function add(a,b) {return (a+b)};
function subtract(a,b) {return (a-b)}:
现在我可以创建一个新函数:
function longWayAroundTheBarn(num1,num2,theFunc)
{
// invoke the passed function with the passed parameters
return theFunc(num1,num2);
}
这样称呼它:
console.log(longWayAroundTheBarn(1,2),add);
> 3
console.log(longWayAroundTheBarn(longWayAroundTheBarn(2,2,subtract),4,add);
> 4
甚至像这样:
console.log(longWayAroundTheBarn(1,2),add);
> 3
console.log(longWayAroundTheBarn(longWayAroundTheBarn(2,2,subtract),4,add);
> 4
显然,这将是一个愚蠢的使用回调,但您可以想象这样“插入”函数的能力会非常强大
考虑一下是否无法传递函数。这可能是实现此功能的一种方法:
function reallyLongWayAround(num1,num2,funcName)
{
if(funcName==='add')
return add(num1 ,num2);
else if (funcName === 'subtract')
return subtract(num1, num2);
}
您可以想象,除了必须编写和维护非常繁琐的代码之外,它的功能几乎没有那么强大,因为reallyLongWayAround
函数只能调用它知道的代码。通过传递函数,我的长时间在仓库中运行
并不关心我是否创建了新函数并将其传递给它。注意,由于弱类型,它甚至不需要关心它正在传递的参数。也许你想实现类似的东西
function businessDaysBetween(d1,d2)
{
// implementation left as a reader exercise
};
打电话给:
longWayAroundTheBarn(new Date(2014,1,15), new Date(2014,1,22),businessDaysBetween)
回到您提出的具体案例,req
和res
不是一个答案所指出的“局部变量”——它们被称为参数或参数。你没有向他们传递任何东西。它们由调用函数传递给您。如果你愿意,你可以叫他们弗雷德和巴尼,尽管这是个糟糕的主意。主要的一点是,它们将被调用,并由请求和响应对象填充
实际上,您甚至不必在函数签名中包含参数,您可以使用如下回调,并通过读取arguments数组来使用传递给函数的第二个参数(注意,它实际上不是数组,但在许多方面的行为类似)。这将是一个可怕的想法,但再次尝试说明这一点
var http = require('http');
http.createServer(function () {
arguments[1].writeHead(200, {'Content-Type': 'text/plain'});
arguments[1].end('Hello World\n');
}).listen(1337, 'myhost');
看看这是否有帮助,所以这是相当整洁的。谢谢你举个例子。这个概念现在开始变得更有意义了。我想看看http.createServer()的源代码。我正在浏览,试图探索一些代码。事实上,这是一个非常强大的概念,对node非常重要。这需要一些时间来适应。
http.createServer()
不是很有趣。当http.createServer()所做的一切都是调用时,您看到了更“有趣”的部分。感谢您花时间对@barry johnson进行了如此详细的解释-我想我终于开始明白了。我真的需要重新思考,这对我很有帮助。