Passing function as callback without argument - need help to understand it - javascript

I've seen a code sample like that in some tutorial:
getSomething(function onSomething(name) {
return renderSomething(name);
});
And that it is equal to the following:
getSomething(renderSomething);
I'm a newbie, and never seen anything like this before. I can't really understand how the above can be the same(without parameter on the renderSomething()).
I've tried to recreate something similar to the above code to better understand it and kind of failed. I'm showing you what I've tried and hopefully you can explain to me why the above is equivalent and the below two questions that came up.
Can you please explain to me:
Why parameter name is undefined?
How come the console.log('a') is printed before the console.log('c')?
var name = 'alex';
console.log('start');
function print(cb) {
console.log('a');
cb();
}
function renderName(name) {
console.log('b');
console.log(name);
}
print(function onPrint(name) {
console.log('name: ', name);
console.log('c');
return renderName(name);
});

To understand how those two statements are equivalent, you really need to look inside of the function and also to reflect on why we use callbacks in the first place. It's also important to understand the difference between function declarations (function getFullName), invocations (getFullName()) and references (getFullName).
We use callbacks to react to something that might happen later, usually the result of whatever has happened is of interest to us. So we create callbacks that receive that result.
Imagine you have a function getFullName, if it was synchronous you would just call it like this:
const fullName = getFullName('John', 'Doe');
And inside the function might simply be:
function getFullName(firstName, lastName) {
return firstName + ' ' + lastName;
}
But for some reason, this function is asynchronous, so you don't get the result directly, so we use a callback to get notified when the name is ready to use:
function getFullName(firstName, lastName, callback) {
// Do something that takes time, then with the result of that
callback(firstName + ' ' + lastName);
}
Now when we call this function, it looks like this:
getFullName('John', 'Doe', function (fullName) {
console.log(fullName);
});
So the getFullName function, will invoke our callback and pass it the value it created. Since your function takes 1 argument, the fullName will be in that argument, no matter what we name that argument. So we can replace our callback (that we've created as an anonymous function) with any other function that takes one argument, such as console.log, like this:
getFullName('John', 'Doe', console.log)
In both these cases, we're sending in a function reference to getFullName, in the first case it's a reference from a function we've just created, in the second it's a reference to a function in the global scope.
You could equally do this:
const myCallback = function(fullName) {
console.log(fullName);
}
getFullName('John', 'Doe', myCallback);
Note how this is different from doing something like this:
getFullName('John', 'Doe', myCallback()); <-- function invocation!
Here, because we are invoking/calling the function, it will execute, and the result of that will be passed as the third argument to getFullName, which isn't what we wanted.
Reading up on first class functions might give you more insight!
As others have mentioned, but for completion, in your example, you never pass some result to your callback, in this case you could pass the variable name or something else to simulate the result being created. And by flipping the order in which you call console.log and cb(name) your logs should make sense.
What you return from your callback function will never really be used, at least not in our example.

Pass the parameter to cb in print function
var name = 'alex';
console.log('start');
function print(cb) {
console.log('a');
return cb(name);
}
function renderName(name) {
console.log('b');
console.log(name);
}
print(function onPrint(name) {
console.log('name: ', name);
console.log('c');
return renderName(name);
});

As to your questions:
Why parameter name is undefined?
Because you didn't pass an argument when you called cb(). It would have worked if for instance you had done cb("John").
How come the console.log('a') is printed before the console.log('c')?
Because that is the very first thing that the print function does. It only calls your callback with cb() after having done that.

Related

How can I use ".call()" method in a javascript function and why does it have a "null" value?

So basically why do I have to use this kind of method in these kind of situations in particular?
function Example(callback) {
// What's the purpose of both 'call()' and 'null'?
callback.call(null, "Hello")
}
Exemple(function(callback) {
alert();
})
I've figured it out this syntax in a open project code but I haven't found out why it works yet.
You don't need to use call() in this situation. call() is used when you need to set the value of this in a function. If you aren't doing that, just call the function like you would any other function. For example:
function Example(callback) {
// call the function passed in
callback("Hello")
// this also works, but there's no benefit here
// because the callback doesn't care about `this`
// callback.call(null, "Hello")
}
// pass a callback function to Example
Example(function(text) {
console.log(text);
})
You would use call in situations where the callback function needs a value for this. For example:
function Example(callback) {
let person = {name: "Mark"}
// set this in the callback to the person object
// and the execute it with the argument "Howdy"
callback.call(person, "Howdy")
}
Example(function(greeting) {
// the callback function depends on having this.name defined
console.log(greeting, this.name);
})
This looks pointless at the first glance, however, there might be valid reasons for this syntax, for example:
the callback relies explicitly on this being null and not some global default
the callback is not necessarily a function, it can be a "function-alike" object that provides a .call method
callback.call(... is used consistently through the application, no matter if this is needed or not

JavaScript Get Function Instance with Arguments Passed In

Say I have the following code.
function myFunc(item) {
console.log(item);
}
function action() {
return myFunc("Hello World");
}
const myUncalledFunction = action;
myUncalledFunction(); // will console.log "Hello World"
Is there a way to make this code cleaner? I've looked into .apply() but it looks like that calls the function immediately as well.
The reason I'm wanting to do this is Chai's expect for throw requires you to pass in an uncalled function. But the function I'm wanting to test requires arguments to be passed in. So currently I just created a wrapper function that returns the function with the arguments passed in.
I feel like there has to be a better way to achieve this that is cleaner and simpler for someone looking at it.
Use .bind to bind arguments (and a calling context, if needed) to a function, which produces a new callable function in the process. Here, you can see this as basically allowing you to pass in arguments at one time, and then call the desired function with those arguments later:
function myFunc(item) {
console.log(item);
}
const myUncalledFunction = myFunc.bind(undefined, 'Hello World');
myUncalledFunction();
Or you might just use a concise arrow function
function myFunc(item) {
console.log(item);
}
const myUncalledFunction = () => myFunc('Hello World');
myUncalledFunction();

IndexedDB - Can't pass variable after onsuccess when opening database

I have been looking for assistance with setting up an IndexedDB for web storage, and I have run into a problem that I cannot find a good answer to. After I have successfully setup/opened the database I am having trouble passing the variable that contains the database information to access it later. Here is my code, I have been following a guide from MDN :
const DB_NAME = 'database-name';
const DB_VERSION = 2;
const DB_STORE_NAME = 'users';
var db;
function openDb() {
console.log('openDb ...')
var request = indexedDB.open(DB_NAME, DB_VERSION);
request.onsuccess = function(event) {
db = request.result;
console.log("openDb DONE");
};
request.onerror = function(event) {
console.log(request.errorCode);
};
request.onupgradeneeded = function(event) {
console.log('openDb.onupgradeneeded');
var store = event.currentTarget.result.createObjectStore(DB_STORE_NAME, { keyPath: 'id', autoIncrement: true });
store.createIndex('age', 'age', { unique: false });
};
}
function getObjectStore(store_name, mode) {
var tx = db.transaction(store_name, mode);
return tx.objectStore(store_name);
}
When getObjectStore is called the variable db is undefined. My knowledge of javascript is very limited and some concepts I don't get. The guide doesn't not show anything special being done and their demo works as is. Some other guides have mentioned implementing a callback, but they don't show how its done nor do I understand the concept of callbacks. Any help is appreciated. Thanks.
Unfortunately you need to learn about a relatively complicated concept usually referred to as asynchronous JavaScript before proceeding to use indexedDB. There are already several thousand questions related to AJAX on stackoverflow. I am trying to think of the most polite way to say this, but basically, the answer you are looking for is already provided by these other questions, and by many other websites. Nevertheless, here are some quick tips.
First, your approach is never going to work. You cannot skip over learning about async.
Second, do not use the setTimeout trick to get it to work. That is horrible advice.
Third, at a general level, a callback is simply a word used to describe a function when the function is used in a particular way. Specifically, a callback refers to a function that is passed as an argument to another function, where the other function then maybe calls the function at some later point in time. More specifically, a callback is generally a function that is called at the end of the function it is passed to, when the function has completed.
For example:
function a(b) { alert(b); }
function c(d) { d('hi'); }
c(a);
That might look a bit confusing at first but it is the simplest thing I can describe off the top of my head. In the example, the final line calls function c and passes in function a. The effect of the code is that you see 'hi' as a browser alert. In this example, the function a is passed as a parameter/argument to function c. Function c uses the name d for its one and only argument. c calls d with the string 'hi'. When describing this example, we would say that argument d represents a callback function passed to function c. We could also say that function a is the particular callback function used by function c. So that is basically it. When you pass a function in as an argument and the other function calls the passed in argument, you are using a callback.
Then things gets way more complicated, because you have to learn about how to read and write asynchronous code. Properly introducing it would take several pages. Here is an extreme crash course.
You have traditionally been writing synchronous code, even if you did not call it that. Synchronous code runs exactly when you expect it to, in the order that you write your statements. Here is a brief example of typical sync code:
function sum(a, b) { return a + b; }
alert(sum(1, 2));
Simple stuff. The next example is code that uses a callback, but is still synchronous.
function doOperation(op, num1, num2) { return op(num1, num2); }
function sumOperation(num1, num2) { return num1 + num2; }
var result = doOperation(sumOperation, 1, 2);
alert(result);
Here we passed the sumOperation function into the doOperation function. sumOperation is the callback function. It is the first argument with the name 'op'. Still pretty simple stuff. Now consider the next example. The point of the next example is to show how we pass control to the function to do something. Kind of like how goto/labels work.
function doOperation(op, num1, num2) {
var result = op(num1, num2);
alert(result);
return undefined;
}
function sumOperation(num1, num2) { return num1 + num2; }
doOperation(sumOperation, 1, 2);
Notice how doOperation no longer returns a value. It has the logic within its function body. So once we call doOp, the browser starts running the code inside doOperation. So we switched from the outer context into the body of the function. Also, because doOperation doesn't return anything, we cannot do anything with its return value. The logic is locked inside the body of the doOperation function. The code still works about the same, its just that now we are not returning anything from doOperation, and now the logic is inside doOperation instead of outside in the main/global context.
Now an example that uses setTimeout. This is completely unrelated to the suggestion of using setTimeout.
function doOperation(op, num1, num2) {
setTimeout(function runLater() {
var result = op(num1, num2);
alert(result);
return undefined;
}, 1000);
return undefined;
}
function sumOperation(num1, num2) { return num1 + num2; }
doOperation(sumOperation, 1, 2);
The point here is to understand that we use a callback (named runLater in this example), and that the code inside the callback does not run immediately. Therefore, we can no longer say it runs synchronously. We instead refer to the statements constituting the body of the callback function as asynchronous. So now an alert appears after 1 second. Notice how we cannot return anything from runLater. Also notice how we cannot return anything from doOperation. There is nothing to return. There is no way to get the value in the 'result' variable out of the scope of runLater. It is locked in there.
Let's try almost the same thing, but try to have runLater set a variable. Also, I am going to omit 'return undefined' because that is what every function without a explicit return statement returns.
var aGlobalResult = null;
function doOperation(op, num1, num2) {
setTimeout(function runLater() {
aGlobalResult = op(num1, num2);
}, 1000);
}
function sumOperation(num1, num2) { return num1 + num2; }
doOperation(sumOperation, 1, 2);
alert(aGlobalResult);
Hopefully you are catching on to the problem. First off, runLater does not return anything, so doOperation does not return anything, so we could not even try to do something like aGlobalResult = doOperation(...);, because that would not make any sense. Second, the result here is that you will see an alert 'undefined' because the alert statement executes prior to the statement that assigns a value to aGlobalResult. This is even though you wrote the assignment statement higher up (earlier) in the code, and the alert is later. This is the brick wall some newer developers run into right here. This is indeed confusing for some. aGlobalResult is undefined here because setTimeout does not set it until later. Even if we passed in 0 milliseconds to setTimeout, it is still 'later', meaning that the assignment happens at a later point in time, after the alert. The alert message is always going to be undefined. There is absolutely nothing you can do to avoid the way this works. Nothing. Period. Stop trying. Learn it, or give up entirely.
So, how does one typically write code that behaves or involves asynchronous stuff? By using callbacks. Which again means that you can no longer use return statements to assign values to outer scope variables. You instead want to write functions and pass around control to various functions. In other words, instead of:
function a() {}
function b() {}
function c() {}
a(); b(); c();
you write code like this:
function a(callback) {
var asdf = 1+2; // do some stuff in a
alert('a finished');
// a has now completed, call its callback function, appropriately named callback
callback();
}
function b(callback) {
var asdfasdfasdf = 3 + 4;
alert('b finished');
// call the callback
callback();
}
a( function(){ b(function() { alert('both a and b finished'); }); });
This is more formally known as continuation passing style, or CPS.
So, that is an example of the very basics of writing callback functions and basic asynchronous code. Now you can start to use indexedDB. The first thing you will notice is that the function indexedDB.open is documented as asynchronous. So, how can we use it? Like this:
var someGlobalVariable = null;
var openRequest = indexedDB.open(...);
openRequest.onsuccess = function openRequestOnSuccessCallbackFunction(event) {
// Get a reference to the database variable. If this function is ever called at some later
// point in time, the database variable is now defined as the 'result' property of the
// open request. There are multiple ways to access the result property. Any of the following
// lines works 100% the same way. Use whatever you prefer. It does not matter.
var databaseConnection = openRequest.result;
var databaseConnection = this.result;
var databaseConnection = event.target.result;
var databaseConnection = event.currentTarget.result;
// Now that we have a valid and defined databaseConnection variable, do something with it
// e.g.:
var transaction = databaseConnection.transaction(...);
var objectStore = transaction.objectStore(...);
// etc.
// DO NOT DO THE FOLLOWING, it does not work. Why? Review the early descriptions. First off
// this onsuccess callback function does not return anything. Second off this function gets
// called at some *later* point in time, who knows when. It could be a nanosecond later.
someGlobalVariable = databaseConnection;
};
Hopefully that sets you on the path.
Edit: I thought I would add a bit more of an intro. A related concept you need to learn that I did not explain clearly enough regarding control is the difference between imperative and declarative programming.
Imperative programming involves executing a series of statements in the order you wrote. You are the caller and are in control. Imperative code looks like this (fictional code):
var dbConn = dbFactory.newConnection('mydb');
var tx = dbConn.newTransaction();
var resultCode = tx.put(myObject);
if(resultCode == dbResultConstants.ERROR_PUT_KEY_EXISTS) {
alert('uhoh');
}
Declarative programming is subtly different. With a declarative approach, you write functions, and then you register (aka hook or bind) the functions to the JavaScript engine, and then at some point later, when it is appropriate, the engine runs your code. The engine is the caller and is in control, not you. Declarative programming involves callbacks and looks like this (fictional code):
dbFactory.newConnection(function onConnect(dbConn) {
dbConn.newTransaction(function onNewTransaction(tx) {
tx.put(myObject, function onPut(resultCode) {
if(resultCode == dbResultConstants.ERROR_PUT_KEY_EXISTS) {
alert('uhoh');
}
});
});
});
In this example, the only thing you called was the fictional dbFactory.newConnection function. You passed in a callback function. You did not call the callback function yourself. The engine calls the callback function. You cannot call the callback function yourself. This is kind of the whole idea behind why JavaScript engines can allow you to write asynchronous code. Because you don't get to control the order of execution of statements/functions. The engine gets to control it. All you get to do is write your functions, register them, and then start a chain of callbacks (the sole imperative line, the starting statement).
So this is why a function like getObjectStore in your question will not work. You are trying to call the function yourself, but that is backwards. You can only write a function and register it (somehow hook it up as a callback somewhere) and then the engine, not you, calls it at some later point in time.
Hopefully this is not more confusing, but you could actually write your function getObjectStore if you really wanted to by passing in the database variable to the function as its first argument. This leads to the logical next question, how to get a valid database variable to pass into the function. You cannot get one in a global context (reliably). Because the connection variable is only valid within the context of the onOpen callback function. So you would have to make your call to this function from within the onOpen function. Something like:
function getObjectStore(db, name, mode) {
var tx = db.transaction(name, mode);
var store = tx.objectStore(name);
return store;
}
var openRequest = indexedDB.open(...);
openRequest.onsuccess = function onOpen(event) {
// get the connection variable. it is defined within this (onOpen) function and open.
var db = this.result;
// call our simple imperative helper function to get the users store. only call it from
// within this onOpen function because that is the only place we can get the 'db' variable.
var usersStore = getObjectStore(db, 'users', 'readwrite');
// do something here with usersStore, inside this function only.
};

Are javascript callbacks just anonymous functions sent as an argument in a function call?

Are Javascript callbacks just anonymous functions sent as an argument in a function call?
For example,
mySandwich('ham', 'cheese', function() {
alert('Finished eating my sandwich.');
});
JavaScript callbacks are functions passed as values into an asynchronous function for the purpose of continuation.
Functions are values:
So in JavaScript, you can pass a functions around like values. You can reference a function in a number of ways:
Pass a literal anonymous function as the callback
doSomeWork(function (err, result) {
if (err) {
throw new Error(err);
} else {
console.log(result);
}
});
Pass a literal named function as the callback
doSomeWork(function magicalCallback(err, result) {
if (err) {
throw new Error(err);
} else {
console.log(result);
}
});
(Naming every function is a smart idea because you can see it in the stack trace)
Pass in the value of a variable which happens to be storing a function as the callback
var someFunction = function callItWhatYouWant(err, result) {
if (err) {
throw new Error(err);
} else {
console.log(result);
}
}
// reference the callback stored in the someFunction variable
doSomeWork(someFunction);
Pass in the function by referencing the function name as the callback
function callItWhatYouWant(err, result) {
if (err) {
throw new Error(err);
} else {
console.log(result);
}
}
// reference the callback function using the function name
doSomeWork(callItWhatYouWant);
Continuation?
Continuation is all about the next step. When you call a function which is asynchronous, it needs to notify you that it is done. The callback acts as the next step, i.e. the asynchronous function will call you back when it is done.
So a callback is just a function argument used for a particular purpose, that being, continuation.
Callback signature
There is no standard for which arguments a callback should take, but in the Node.js community we have adopted the general signature
function (err, result)
where err is an Error object if something bad happened, or null if things were successful. If things went bad result is generally undefined, otherwise it contains the result. So your callback is generally called by either
callback(new Error("oops"));
or
callback(null, result);
Also note that it's normal for the last parameter of an asynchronous function to be the callback parameter
function callLater(delay, args, callback) {
setTimeout(function () {
callback(null, args);
}, delay);
}
In your example: yes
But in m example: No
function myCallback()
{
alert('finished eating my sandwich');
}
mySandwich('ham','cheese', myCallback);
So, from you comment I think the real question is: What is an anonymous function? I did my best, but it is still early in the morning here, so don't shoot me.
Well, gooed question. Hard answer
when defining a function, it lives withing its scope. Scope? huh? Ok, let's start again.
when a webpage is loaded, the browser creates a window object. It then starts parsing everything you wrote in that document (let's assume HTML).
Every DOMElement it encounters, gets put into the window.document object. Every Element inside the widnow.document element is rendered/interpreted in your browser window.
Now, the browser encounters the following <script>:
var myVariable = 'So cool';
The browser sees var myVariable. This tells him to create a variable called myVariable in the current scope (again that word). the current scope is window (the window object the browser created). So it adds the variable to the window object:
window.myVariable === myVariable
The same goes for functions
function myAwesomeFunction()
{
alert('I am so cool');
}
Creates a function inside the current scope (window) with the name myAwesomeFunction. So again:
window.myAwesomeFunction === myAwesomeFunction
But what if I want to create a function I don't whant any other code to have access to? What if I want a function that should only exist when a certain specific button is clicked.
Well, enter anonymous functions. these are functions that are declared in the anonymous scope. they cannot be accessed using the window object:
myButton = document.getElementById('myButton'); // === window.document.getElementById('myButton');
myButton.addEventListener('click', function()
{
alert('I am so awesome');
});
Now, the function you passed into the eventlistener only lives inside the eventListener. It doesn't even have a name. So it's scope is 'the on click event of the button' but we can't access it from outside because it doesnt have a name. Thus, anonymous function.
A good read would be to google stuff like 'javascript scope', 'javascript window object', ... A lot of good articles give a better in depth explanation of all the words I threw at you.
Yes, except that they don't have to be anonymous functions, and there's a bit more to the definition of a callback. The other two answers have covered the details of what callbacks are for and anonymous functions well, but I have had similar confusion to yours when I was first learning so I wanted to add a missing piece. So, your example:
mySandwich('ham', 'cheese', function() {
alert('Finished eating my sandwich.');
});
I've noticed most callback explanations are like this- they don't include the declaration of the larger function, in this case mySandwich. But yes, the function this is being passed into does need to explicitly call the callback function for it to run. So your mySandwich function might look like this:
function mySandwich(meat, topping, callback) {
//some code here using meat and topping
//some code here about eating the sandwich
callback();
}
So your code passes those parameters, including the function, into the mySandwich function, which then invokes it. Because many times the top-level function we are using is a method from a library rather than part of our own code, we don't actually see the step where the callback is invoked, but it does still happen and doesn't just automatically execute itself.
So yes, a callback is really just a function being passed as a parameter to another function, and then it is invoked usually as the last thing to happen in that larger function. There's more than that to callbacks, but they operate by the same rules as other functions in that somewhere they have to be declared and somewhere they have to be called, otherwise they don't run.

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.
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).
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
});
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);
A couple notes:
If you want to propagate the result of the callback then you need to return its output in RandHash
You don't need ds_hash to be a global variable if you're planning on returning it, anyway
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.
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);

Categories

Resources