Node JS匿名函数和回调

nf0*_*590 6 javascript http callback node.js

有人请帮帮我.我一直在阅读大量的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/');
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么可以在上面的匿名函数中使用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
          });
Run Code Online (Sandbox Code Playgroud)

如果你可以发布一个模仿这个过程和语法的小例子,或解释这些回调函数如何像这样工作,或者我如何将这些未声明的变量传递给这样的函数,我将非常感激.

下面发布的答案的类似示例.

     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
     });
Run Code Online (Sandbox Code Playgroud)

bar*_*son 10

主要问题是Javascript是一种函数式语言,因此您可以将函数作为参数传递给其他函数.例如,在其他语言中,您可能经历过将指针或句柄传递给函数.考虑一下你有一些数学函数的简单情况:

function add(a,b) {return (a+b)};
function subtract(a,b) {return (a-b)}:
Run Code Online (Sandbox Code Playgroud)

现在我可以创建一个新函数:

function longWayAroundTheBarn(num1,num2,theFunc)
{
    // invoke the passed function with the passed parameters
    return theFunc(num1,num2);
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

console.log(longWayAroundTheBarn(1,2),add);

> 3
Run Code Online (Sandbox Code Playgroud)

或者甚至像这样:

console.log(longWayAroundTheBarn(longWayAroundTheBarn(2,2,subtract),4,add);

> 4
Run Code Online (Sandbox Code Playgroud)

显然这将是一个愚蠢的使用回调,但你可以想象一般,以这种方式"插入"函数的能力可能非常强大.

考虑一下你是否无法传递函数.这可能是您实现此目的的一种方式:

function reallyLongWayAround(num1,num2,funcName)
{
    if(funcName==='add')
        return add(num1 ,num2);
    else if (funcName === 'subtract')
        return subtract(num1, num2);
}
Run Code Online (Sandbox Code Playgroud)

你可以想象,除了必须编写和维护真正乏味的代码之外,它还不是那么强大,因为该reallyLongWayAround函数只能调用它所知道的代码.通过传递函数,我longWayAroundTheBarn不关心我是否创建新函数并将其传递给它.请注意,由于键入较弱,它甚至不需要关心它传递的参数.也许你想实现类似的东西

 function businessDaysBetween(d1,d2)
 {
     // implementation left as a reader exercise
 };
Run Code Online (Sandbox Code Playgroud)

它可以正常工作:

longWayAroundTheBarn(new Date(2014,1,15), new Date(2014,1,22),businessDaysBetween)
Run Code Online (Sandbox Code Playgroud)

回到你提出的特定情况,req并且res不是"局部变量",如一个答案所示 - 它们被称为参数或参数.你没有把任何东西传递给他们.它们由调用函数传递给您.你实际上可以打电话给他们fred,barney如果你愿意,虽然这会是一个糟糕的主意.重点是它们将被调用填充请求和响应对象.

事实上,你甚至不必有你的函数签名的参数,你可以只是一个回调的下方,通过读取参数数组(注意利用传递给你的函数的第二个参数,它并不是一个真正的数组,但在许多方面表现相似).这将是一个可怕的,可怕的想法,但再次,试图说明这一点.

      var http = require('http');
      http.createServer(function () {
             arguments[1].writeHead(200, {'Content-Type': 'text/plain'});
             arguments[1].end('Hello World\n');
      }).listen(1337, 'myhost');
Run Code Online (Sandbox Code Playgroud)


Max*_*xim 1

您应该使用文档。例如,对于 createServer,请遵循此页面 - http://nodejs.org/api/http.html#http_http_createserver_requestlistener

http.createServer ([requestListener])#返回一个新的Web服务器对象。

requestListener 是一个自动添加到 “request”事件中的函数。

然后,您检查“请求”事件 -

事件:'请求' #函数(请求,响应) {}

每次有请求时发出。请注意,每个连接可能有多个请求(在保持活动连接的情况下)。request 是 http.IncomingMessage 的实例,response 是 http.ServerResponse 的实例。

关于流,完全相同。这里的文档 - http://nodejs.org/api/stream.html#stream_writable_stream

寻找

事件:“数据”