Node JS匿名函数和回调

时间:2014-03-27 02:55:43

标签: javascript node.js http callback

有人请帮助我。我一直在阅读大量的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
     });

4 个答案:

答案 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)

回到您提出的具体案例,reqres不是'局部变量'正如一个答案所示 - 它们被称为参数或参数。你没有把任何东西传递给他们。它们由调用函数传递给您。如果你愿意,你实际上可以称他们为fredbarney,尽管这可能是一个糟糕的主意。重点是它们将被调用填充请求和响应对象。

你实际上甚至不需要在函数签名中包含参数,你可以只使用如下所示的回调,并通过读取参数数组来使用传递给函数的第二个参数(注意,它& #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

寻找

  

活动:'数据'