chuckjones242
chuckjones242

Reputation: 165

basic node.js callbacks assigned to variable

I've been struggling for awhile with callbacks in general. I'm trying to go back to the basics to try to understand conceptually and this is what I understand so far (yeah, basic).

function RandHash (callback) {
  ds_hash = Math.floor((Math.random()*10000)+1); 
  callback();
}

function CompiledHash (){
  console.log(ds_hash);
}

var ds_hash;
RandHash(Compiled Hash);

Will yield the random number.

However, I'm lost as to how to get the "ds_hash" variable returned from the callback.

Seems this would work:

var ds_hash;
ds_hash = RandHash(Compiled Hash);

It doesn't. If I try to return the value something like:

function CompiledHash (){
  return ds_hash;
}

It doesn't do anything.

Please help me with this. Seems I spend 90% of my time with node in callback debugging. I've built some decent applications but everything has been handled through the async library because of this mental block I have.

Thanks.

Upvotes: 3

Views: 8885

Answers (5)

Lawrence Jones
Lawrence Jones

Reputation: 955

The first error you've made is that RandHash hasn't returned anything. There's no return statement present in the function, so var anything = RandHash(alsoAnything) will always result in anything being undefined.

Functions are first class variables

Functions can be used just as variables can, and passed round as arguments to functions. This is a powerful feature of javascript and something that you'll need to grok to use callbacks. Think of a function as a defined action, and you're just passing that action around.

Also, callbacks should be used to deal with the completion of a process. So the idea is, you know what is meant to happen after process A, and what it is meant to generate, so you can give process A a callback which will be called once A has terminated. Now the scenario here isn't appropriate for a callback situation. It would be much easier for you to do...

function RandHash () {
  return Math.floor((Math.random()*10000)+1);
}

And then get your hash by just calling this function, like so...

var hash = RandHash();

You also want to be aware of javascripts variable scoping, as you're missing the var keyword when referencing ds_hash in the RandHash function which means the assignment defaults to global scope. This is probably what is responsible for confusing you, as your assignment of ds_hash in RandHash will be global and therefore available in CompiledHash, meaning some functions will still be able to access the ds_hash value despite this not being the correct, or proper way to do this.

Assuming you will eventually require asynchronous processing

function randHash (callback) {
  var hash = /* do hash calculation */
  callback(hash);
}
function compileHash (hash) {
  /* do something using the hash variable passed to this function */
}

randHash(compileHash);  // pass the compileHash function as the callback

You should pass your variables as arguments to the callback. That will deal with your scoping issues hopefully.

Also, small note, functions in javascript should typically be lowercase if they aren't going to be used with the new statement (ie, a javascript class).

Upvotes: 3

Alex Shilman
Alex Shilman

Reputation: 1547

This will do

function RandHash (callback) {
 var  ds_hash = Math.floor((Math.random()*10000)+1); 
  callback(ds_hash);
}

var CompiledHash = function (ds_hash){
  console.log(ds_hash);
}


RandHash(CompiledHash);

Upvotes: 0

adeneo
adeneo

Reputation: 318302

To truly understand asynchronous behaviour, you should try it with something that is actually asynchronous, and passing values around, not just a global variable, as that will never work when you move on to asynchronous functions :

function RandHash (callback) {
    setTimeout(function() {
        var ds_hash = Math.floor((Math.random()*10000)+1); 
        callback(ds_hash); // execute callback when async operation is done
    }, 300);
}

function CompiledHash(hash){ // pass hash
  console.log(hash);
}

RandHash(function(returned_hash) { // this is the callback function 
    CompiledHash(returned_hash);   // pass along the returned data
});

The callback function is executed once the asynchronous function, in this case setTimeout, has completed, and passes the data back as an argument.
The callback argument is just the function that is passes as an argument.

// regular function
function doStuff(argument) {
    // where argument can be anything, also a function
}

// you can pass a string
doStuff('string');

// or a function
doStuff(function(argument_returned) {

});

// and passing a function you can execute that function with arguments in the original function
function doStuff(argument) {
     var argument_returned = 'string';
     argument(argument_returned); // executes the passsed function

});

Upvotes: 3

Wayne
Wayne

Reputation: 60414

A couple notes:

  1. If you want to propagate the result of the callback then you need to return its output in RandHash

  2. You don't need ds_hash to be a global variable if you're planning on returning it, anyway

  3. The line RandHash(Compiled Hash); is a syntax error (notice the space in the variable name)

Try this:

function RandHash(callback) {
    var ds_hash = Math.floor((Math.random() * 10000) + 1); 
    return callback(ds_hash);
}

function CompiledHash(ds_hash) {
    console.log(ds_hash);
    return ds_hash;
}

RandHash(CompiledHash);

Notice that there are no global variables. The callback returns a value and the function that executes the callback passes it along.

On a style note, you should only capitalize the names of functions that you intend to use as a constructor.

Upvotes: 1

tpae
tpae

Reputation: 6346

Try this:

function RandHash (callback) {
  ds_hash = Math.floor((Math.random()*10000)+1); 
  callback(ds_hash);
}

function CompiledHash(ds_hash){
  console.log(ds_hash);
}

var ds_hash;
RandHash(CompiledHash);

For callbacks and functions, it's a bit difficult to understand variable scopes, and what you are doing is not really recommended. You can pass parameters into callbacks, and should get passed, but I would suggest building it like this:

function RandHash (callback) {
  var ds_hash = Math.floor((Math.random()*10000)+1); 
  callback(ds_hash);
}

function CompiledHash(ds_hash){
  console.log(ds_hash);
}

RandHash(CompiledHash);

Upvotes: 1

Related Questions