Javascript functions with a parameter that have a function?

please explain to me how this works. I'm new to nodejs and the way they set up their code is very complicated to me to properly understand..

I split the code that I don't understand into little snippets. You can find the whole code below.

callback(function() {
  results.push(Array.prototype.slice.call(arguments));
  next();
});

I don't understand the above snippet. It seems like this anonymous function becomes the next argument of the series anon function? Will the code in the anon function arguments execute?

function(next) { async(1, next); }

Which will execute first? The async function execution in the series functions or the next parameter execution?

Here I attached the full code:

function series(callbacks, last) {
  var results = [];
  function next() {
    var callback = callbacks.shift();
    if(callback) {
      callback(function() {
        results.push(Array.prototype.slice.call(arguments));
        next();
      });
    } else {
      last(results);
    }
  }
  next();
}

function async(arg, callback) {
  var delay = Math.floor(Math.random() * 5 + 1) * 100;
  console.log('async with \''+arg+'\', return in '+delay+' ms');
  setTimeout(function() {
    callback(arg*2);
  }, delay);
}

function final(results) {
  console.log('Done', results);
}

series([
  function(next) { async(1, next); },
  function(next) { async(2, next); },
  function(next) { async(3, next); },
  function(next) { async(4, next); },
  function(next) { async(5, next); },
  function(next) { async(6, next); }
], final);

First, know that in JavaScript, functions can be passed as parameters to other functions. This is very different than passing the value returned from another function. Take this simple example:

function A() {
    alert("In A"); 
}

function B(fn) {
    alert("In B");
    fn(); 
}

B(A);   // alerts "In B", then "In A".

B(A()); // alerts "In A", then "In B", 
        // (then errors because the return value from A is undefined, 
        // and thus cannot be invoked.)

So, to follow your code example from beginning to end, here's how it goes...

  1. series is a function that takes an array of functions (callbacks) and one more function (last) as parameters. It gets invoked first.

  2. Within series, a function named next is defined (not to be confused with the parameter to each of the callback functions named next). The function next is invoked.

  3. Within next, a variable named callback is defined. It's value is one of functions from the callbacks array in turn. The function stored in the callback variable gets invoked with an anonymous function.

  4. Within callback, the async function is invoked. The same anonymous function from step 3 is passed to async. It's now called next, but this has nothing much to do with the next function defined in series.

  5. Within async, some calculations are done and eventually the anonymous function is invoked (via setTimeout). It's called callback within the async function.

  6. Within the anonymous function, some values are pushed onto the results array, and next is invoked. This is the next function defined in series.

  7. Repeat steps 3 through 6 until all the functions within callbacks have been invoked and then the function in the parameter last (final) is invoked.

Clear as mud, right?

The series function takes a lists of functions to execute. Each of this functions must take a single parameter that needs to be a function, a callback. series uses that callback to know that a function finished its async work.

Here's a step by step of what series does:

  1. Take a list of functions and a single callback named last
  2. Create a results array where we'll store the results of all those functions
  3. Pick the first item in the list and remove from the list
  4. If the item is not a function (the list is empty):
    1. Call last with the results array
    2. Stop. We're done
  5. If the item is a function call it and pass it a new callback that lets us know when it's done
  6. Once the function is done doing its async work it should call the callback with any number of parameters. Store those parameters in the results array
  7. Go to 3

Basically, it's a recursive function that waits until a process is done between each step. The results will be that each function you pass it in its callbacks list will be called sequentially, each after the previous finished doing its work.

Don't be discouraged. Async code is hard even for seasoned programmers.