1

I'm new to the Node.js platform and I'm trying to learn as much as I can. After playing with callbacks one thing really confuses me:

So, I have this function :

    function registerUser(body, res, UserModel){

    var userJSON =  {
        email : body.email,
        password : body.password,
        accessToken : null
    };
    var user = null;
    var userAlreadyExists = false;

    UserModel.find({}).select('email').exec(function(err, results){
        if(err){
            console.log('Database error : ' + err);
         // send the appropriate response

        }else{
            for(var index in results){
                if(results[index].email == userJSON.email){
                    userAlreadyExists = true;
                    break;
                }
            }
            if(userAlreadyExists){
                // send the appropriate response
            }else{
                  newAccessToken(UserModel, function(error, token){
                    if(error != null){
                           // handle the error
                    }else{
                        userJSON.accessToken = token;
                        user = new UserModel(userJSON);
                        user.save(function(err){
                            if(err){
                               // .. handle the error
                            }else{
                               // .. handle the registration
                            }
});}});}}});}

And then the function which accepts the callback:

function newAccessToken(UserModel, callback){

    UserModel.find({}).select('email accessToken').exec(function(err, results){
        if(err){
            callback(err, null);
        }else{
          // .... bunch of logic for generating the token
            callback(null, token);
        }

    });
}

I would expect the callback to not work(maybe throw an error) since both user and userJSON are not defined in it's context.(well, that's not exactly true, but since it is executed async - after a while - , I would expect the callback to lose it's references to those variables, which were defined locally in the registerUser function). Instead this example works perfectly, the callback function keeps it's references with those two variables defined in the registerUser function. Could somebody explain me how the async callback and the references work and why does the example work?

2 Answers 2

2

Instead of callbacks, those are called closures, and in JavaScript the scope treatment is special. Check this document:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

Sign up to request clarification or add additional context in comments.

2 Comments

so the closure keeps it's references with the variables defined in the main function even if the closure is executed after some period of time like 1 minute for example?
Yes, don't worry about time, the function is executed within the scope of the calling function.
1

H i, the function you 'calllback to' is within the scope of the variables you are trying to access, so all good to go for accessing them.

This is not a nodejs thing, regular JS works the same way .

The difference

1) Will not be able to access a var called 'foo'

function finishfunction() {
  console.log(foo); /*  undefined */
}

   function functionwithcallback(callback) {
       callback();
  }

  function doStuff() {

     var foo = "bar";

    functionwithcallback(finishfunction);

 }

 doStuff();

2) like yours, access to 'foo' is fine.

   function functionwithcallback(callback) {
       callback();
  }

  function doStuff() {

     var foo = "bar";

    functionwithcallback(function() {

    console.log(foo) /* all fine */

    });

 }

 doStuff();

2 Comments

even if the closure is executed after 5 mins for example, it will still keep the references towards those variables?
yes, all stays in scope. Give it a try. I call these just regular callbacks btw (a timed function being 'called back' when it is done ). Closures, ( a function in a function), would be better named for objects(functions) with methods and private variables, and are updating the privately scoped variables of the object(function) from multiple sources.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.