Trouble understanding Node.js callbacks

Today is my first foray into nodejs and I am particularly stumped trying to understand the way the following piece of logic flows. The logic is as follows:

request({ uri: db.createDbQuery('identifier:abcd1234') },
                    function(err, response, body) {
                        response.should.have.status(200);
                        var search = JSON.parse(body);
                        search.response.numFound.should.equal(1);
                        done();
                    });
        });

At a higher level I do understand is that an http request is being made and the function is being called at some juncture that is taking the response and doing something to it. What I am trying to understand is the proper order of the calls and how does the binding of variables take place in the above given logic. How does the compiler know how to bind the return values from the request to the anonymous function? Basically, I want to gain an understanding on how things work under the hood for this snippet.

Thanks

Your question isnt specific to node.js, this is basically a feature of javascript.

Basically you are calling request() which is defined like function request(obj, callback)

Internally, the http request is being called, and once its completed, it calls callback which is actually a function pointer.

function request(obj, callback){
    //http request logic...
    var err = request_logic_internal_function();
    var response = ...
    var body = ...


    callback(err, response, body)
}

Your code can actually be restructured as :

var options = { uri: db.createDbQuery('identifier:abcd1234') };
var request_callback = function(err, response, body) {
                        response.should.have.status(200);
                        var search = JSON.parse(body);
                        search.response.numFound.should.equal(1);
                        done();
                    };
request(options, request_callback);

What you're basically doing is sending in a function pointer as a variable.

I don't know what library(ies) you're using, and it looks like you may have anonymized them by assigning methods into your code's global scope like request, done, and db.

What I can say is this:

  1. That indentation is horrible and initially misled me on what it was doing, please gg=G (vim syntax) your code so it's properly indented.
  2. request takes two arguments, a configuration object and a callback.
  3. db.createDbQuery must be a blocking method or the anonymous object you're creating won't have the proper value.
  4. request uses that configuration value, makes a non-blocking I/O request of some kind, and later will call the callback function you provide. That means that the code immediately after that request call will execute before the callback you provide will execute.
  5. Some time later the request data will come back, Node.js's event loop will provide the data to the library's registered event handler (which may or may not be your callback directly -- it could do something to it and then call your event handler afterwards, you don't know or really care).
  6. Then the function does some checks that will throw errors if they fail, and finally calls a done function in its scope (defined somewhere else) that will execute and continue the logical stream of execution.