winger
winger

Reputation: 23

Node.js - Argument in an anonymous function without passing it a variable?

I come from a C/C++ background and I'm having real trouble trying to wrap my head around the syntax of node.js. Anyway, I found some code online to explain the difference between blocking and non-blocking code, and it's had me stumped for hours. I've tried searching and reading books but just can't find an answer to this. The example code retrieves a user ID from a database.

Blocking Version:

function getUser(id) {
   var user = db.query(id);
   return user;
}

console.log('Name: ' + getUser(432).name);

Non-Blocking Version (Node.js):

function getUser(id, callback) {
   db.query(id, callback);
}

getUser(432, function (user) {
   console.log(user.name);
});

I'm fine with the Blocking version because in that instance, the user ID is assigned to the variable user. What I just can't seem to understand is the user argument in the anonymous function. It seems that user just appears out of nowhere and then has instructions acted upon it, without any relationship to an existing variable.

How does the program know what user is? How does it even make any connection with the user's ID? I honestly can't tell if it's my lack of knowledge of JavaScript/Node, or whether the person who wrote this code didn't bother to complete it. All I know is, this makes no sense in C/C++.

Upvotes: 1

Views: 1134

Answers (2)

Tesseract
Tesseract

Reputation: 8139

Maybe it will help you if I translate your example into C. I haven't used C in a long time but I think it would look like this.

void getUser(int id, void (*callback)(User)) {
   db.query(id, callback);
}

void printUserName(User user) {
  printf(user.name);
}

getUser(432, &printUserName);

Upvotes: 1

Madara's Ghost
Madara's Ghost

Reputation: 174977

Well, you've asked the program to fetch you a user, and supplied with a function that accepts an argument (or more, depending on the library). After the operation is complete, getUser will invoke the callback you passed with the result of the operation.

Here's a dummy getUser implementation for you:

function getUser(id, callback) {
    setTimeout(function() {
        var result = {id: id, name: "Madara"};
        callback(result);
    }, 1000); // Wait a second before doing it. Asynchronous!
}

getUser(42, function(user) { console.log(user); });

That function will wait one second, and then invoke the callback you pass with one argument, in this case, an object with the ID you passed, and "Madara" as the name.

Notice that there's nothing blocking with getUser, so getUser returns immediately, and without waiting for the callback to be called.

Upvotes: 3

Related Questions