有人请帮助我。我一直在阅读大量的javascript文档并摆弄javascript。
我可以使用这些功能,但是我不会在这里找到这个必要的句法爵士乐
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
});
答案 0 :(得分:9)
主要问题是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
显然,这将是一个愚蠢的使用回调,但你可以想象一般,插入'插件的能力。这种方式的功能非常强大。
考虑一下你是否能通过功能。这可能是您实现此目的的一种方式:
function reallyLongWayAround(num1,num2,funcName)
{
if(funcName==='add')
return add(num1 ,num2);
else if (funcName === 'subtract')
return subtract(num1, num2);
}
你可以想象,除了必须编写和维护真正乏味的代码之外,它还不是那么强大,因为reallyLongWayAround
函数只能调用它知道的代码。通过传递函数,我的longWayAroundTheBarn
并不关心我是否创建新函数并将其传递给它。请注意,由于键入较弱,它甚至不需要关心它传递的参数。也许你想实现像
function businessDaysBetween(d1,d2)
{
// implementation left as a reader exercise
};
调用它可以正常工作:
longWayAroundTheBarn(new Date(2014,1,15), new Date(2014,1,22),businessDaysBetween)
回到您提出的具体案例,req
和res
不是'局部变量'正如一个答案所示 - 它们被称为参数或参数。你没有把任何东西传递给他们。它们由调用函数传递给您。如果你愿意,你实际上可以称他们为fred
和barney
,尽管这可能是一个糟糕的主意。重点是它们将被调用填充请求和响应对象。
你实际上甚至不需要在函数签名中包含参数,你可以只使用如下所示的回调,并通过读取参数数组来使用传递给函数的第二个参数(注意,它& #39; s实际上不是一个数组,但在许多方面表现相似)。这将是一个可怕的,可怕的想法,但同样,试图说明这一点。
var http = require('http');
http.createServer(function () {
arguments[1].writeHead(200, {'Content-Type': 'text/plain'});
arguments[1].end('Hello World\n');
}).listen(1337, 'myhost');
答案 1 :(得分:1)
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
});
答案 2 :(得分:1)
关键是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中指定的内容。
答案 3 :(得分:0)
您应该使用该文档。 例如,对于createServer,请按照此页面进行操作 - http://nodejs.org/api/http.html#http_http_createserver_requestlistener
http.createServer ([requestListener])#返回一个新的Web服务器对象。
requestListener是一个自动添加到的函数 '请求' 事件。
然后,您检查“请求”'事件 -
事件:'请求' #function (请求,响应) {}
每次有请求时都会发出。请注意,可能有多个 每个连接的请求(在保持连接的情况下)。 request是http.IncomingMessage的一个实例,响应是一个 http.ServerResponse的实例。
关于流,完全相同。这里的文档 - http://nodejs.org/api/stream.html#stream_writable_stream
寻找
活动:'数据'