Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node JS anonymous functions and callbacks

Someone please help me. I have been reading a lot of javascript documentation and fiddling with 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.

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
     });
like image 549
nf071590 Avatar asked Mar 27 '14 02:03

nf071590


People also ask

Can you use an anonymous function in a callback?

console. log(Arr. map(function(x){ return myCallback(x+2)})); In JavaScript, callbacks and anonymous functions can be used interchangeably.

How do I call an anonymous function in node JS?

Functions in JavaScript It is then assigned to a variable named f . To call this anonymous function, simply treat the variable f as a function: f("Hello, JavaScript!") })("Hello, world!")

Is it valid to pass an anonymous function as an argument to another function?

Summary. Anonymous functions are functions without names. Anonymous functions can be used as an argument to other functions or as an immediately invoked function execution.

Do anonymous functions get hoisted?

Anonymous functions are never hoisted (loaded into memory at compilation). Named functions are hoisted (loaded into memory at compilation). When invoking an anonymous function, you can only call it after the declaration line. A name function can be invoked before declaration.


1 Answers

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:

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 reallyLongWayAround function could only ever call code it knew about. By passing functions, my longWayAroundTheBarn doesn'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

 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, req and res are 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 fred and barney if you wanted, although it would be a terrible idea. The main point is that they will be called populated with request and response objects.

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');
like image 137
barry-johnson Avatar answered Oct 03 '22 17:10

barry-johnson