Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 节点JS匿名函数和回调_Javascript_Node.js_Http_Callback - Fatal编程技术网

Javascript 节点JS匿名函数和回调

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

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

您应该使用文档。 例如,对于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进行了如此详细的解释-我想我终于开始明白了。我真的需要重新思考,这对我很有帮助。