Reputation: 3442
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?
Upvotes: 1
Views: 394
Reputation: 5226
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();
Upvotes: 1
Reputation: 859
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
Upvotes: 2