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...
series
is a function that takes an array of functions (callbacks
) and one more function (last
) as parameters. It gets invoked first.
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.
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.
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
.
Within async
, some calculations are done and eventually the anonymous function is invoked (via setTimeout
). It's called callback
within the async
function.
Within the anonymous function, some values are pushed onto the results
array, and next
is invoked. This is the next
function defined in series
.
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:
last
results
array where we'll store the results of all those functionslast
with the results
arrayresults
arrayBasically, 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.