javascript Node JS 匿名函数和回调

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22677385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:33:15  来源:igfitidea点击:

Node JS anonymous functions and callbacks

javascriptnode.jshttpcallback

提问by nf071590

Someone please help me. I have been reading a lot of javascript documentation and fiddling with javascript.

有人请帮助我。我一直在阅读大量的 javascript 文档并摆弄 javascript。

I am able to use the functions but I don't quite get this essential syntactic jazz going on here

我能够使用这些函数,但我不太了解这种基本的句法爵士乐在这里进行

          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/');

I cant figure out why its okay to use req and res in the anonymous function above. It's like they live somewhere inside of http. They are not declared anywhere! They are made up variable names in an anonymous function that reference inner objects or something. It's crazy.

我不明白为什么可以在上面的匿名函数中使用 req 和 res 。就好像他们住在 http 里面的某个地方。他们没有在任何地方声明!它们由引用内部对象或其他东西的匿名函数中的变量名组成。这很疯狂。

How does a callback function like this?

这样的回调函数是如何实现的?

or like

或喜欢

          stream.on('data', function(data){  
                //  use data... i dont know where its coming from 
                //  or how it got there, but use it
          });

If you could post a small example that mimics this process and syntax or explain how these callback functions can work like this or how I can pass these undeclared variables into functions like this I would greatly appreciate it.

如果您可以发布一个模拟此过程和语法的小示例,或者解释这些回调函数如何像这样工作,或者我如何将这些未声明的变量传递给这样的函数,我将不胜感激。

A similar example to the answer posted below.

与下面发布的答案类似的示例。

     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
     });

回答by barry-johnson

The main issue is that Javascript is a functional language so you can pass functions as parameters to other functions. In other languages you may have experienced passing a pointer or handle to a function, for example. Consider a simple cases in which you have some math functions:

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

function add(a,b) {return (a+b)};
function subtract(a,b) {return (a-b)}:

Now I could create a new function:

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

function longWayAroundTheBarn(num1,num2,theFunc)
{
    // invoke the passed function with the passed parameters
    return theFunc(num1,num2);
}

And call it like this:

并这样称呼它:

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

> 3

Or even like this:

或者甚至像这样:

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

> 4

Obviously this would be a silly use callbacks, but you can imagine generally that the ability to 'plug-in' a function this way can be pretty powerful.

显然,这将是一个愚蠢的使用回调,但您可以想象一般情况下,以这种方式“插入”一个函数的能力可能非常强大。

Consider if you couldn't pass functions. This might be one way you would implement this:

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

function reallyLongWayAround(num1,num2,funcName)
{
    if(funcName==='add')
        return add(num1 ,num2);
    else if (funcName === 'subtract')
        return subtract(num1, num2);
}

You can imagine that besides being really tedious code to have to write and maintain, it's not nearly so powerful because the reallyLongWayAroundfunction could only ever call code it knew about. By passing functions, my longWayAroundTheBarndoesn't care if I create new functions and pass it to it. Note that because of weak typing, it doesn't even need to care about the parameters it is passing. Maybe you want to implement something like

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

 function businessDaysBetween(d1,d2)
 {
     // implementation left as a reader exercise
 };

It would work just fine to call:

打电话就可以了:

longWayAroundTheBarn(new Date(2014,1,15), new Date(2014,1,22),businessDaysBetween)

Returning to the specific case you raised, reqand resare not 'local variables' as one answer indicates - they are called parameters or arguments. You aren't passing anything into them. They are being passed to you by the calling function. You could actually call them fredand barneyif you wanted, although it would be a terrible idea. The main point is that they will be called populated with request and response objects.

回到您提出的特定案例,reqres不是一个答案所表明的“局部变量”——它们被称为参数或参数。你没有向他们传递任何东西。它们是由调用函数传递给您的。其实你可以打电话给他们fred,并barney如果你想,虽然这将是一个可怕的想法。重点是它们将被称为填充请求和响应对象。

You actually don't even have to have the parameters in your function signature, you could just have a callback as below, and make use of the second parameter passed to your function by reading the arguments array (Note, it's not actually an array but behaves similarly in many respects). This would be a terrible, terrible idea, but again, trying to illustrate the point.

实际上,您甚至不必在函数签名中包含参数,您可以使用如下所示的回调,并通过读取参数数组来利用传递给函数的第二个参数(注意,它实际上不是数组,而是在许多方面表现相似)。这将是一个可怕的、可怕的想法,但再次试图说明这一点。

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

回答by s4m0k

The req and res are actually local variables of the anonymous function.
I have an example below similar to the codes posted in your question.

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
});

回答by i--

The point is that http.createServerfunction takes an argument that is not a variable, but a function, if that makes sense. In javascript you can do that. And that function expects arguments that are specified in it's API. You can make it anonymous, like in your example, or declared like below:

关键是http.createServerfunction 接受一个不是变量的参数,而是一个函数,如果有道理的话。在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');

but in the end it does not matter, it just behaves accordingly to what is specified in its the API.

但最终没关系,它只是根据其 API 中指定的内容进行操作。

回答by Maxim

You should use the documentation. So for example for createServer, follow this page - http://nodejs.org/api/http.html#http_http_createserver_requestlistener

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

http.createServer([requestListener])# Returns a new web server object.

The requestListener is a function which is automatically added to the 'request'event.

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

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

Then, you check the 'request' event -

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

Event: 'request'# function (request, response){ }

Emitted each time there is a request. Note that there may be multiple requests per connection (in the case of keep-alive connections). request is an instance of http.IncomingMessage and response is an instance of http.ServerResponse.

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

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

Regarding the stream, exactly same. The docs here - http://nodejs.org/api/stream.html#stream_writable_stream

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

Look for

寻找

Event: 'data'

事件:'数据'