Reputation: 339
I am trying to call a function AFTER another function has completed. Normally, this is done with callbacks, at least with Node.js. However, when I try to run the following code in Chrome, the callback function seems to execute before the main function. Am I writing my function/callback wrong? Shouldn't the second function (the callback function) only execute after the first one is complete?
If callbacks don't work when the javascript is running client-side in the browser, is there another way I can ensure the second function runs only when the first function is complete?
<html>
<head></head>
<body>
<script>
function firstLoad(callback) {
console.log("firstLoad function fired.");
}
function secondLoad() {
console.log("secondLoad function fired.");
}
firstLoad(secondLoad());
</script>
</body>
</html>
In Chrome Developer Tools Console, the above code gives me:
secondLoad function fired.
firstLoad function fired.
I would expect it to be the other way around.
Upvotes: 0
Views: 554
Reputation: 1419
I'm trying to give a simpler answer here that gets straight to the point, I have edited your code so it's working the way you are expecting it to work and added some comments to explain what's happening:
<html>
<head></head>
<body>
<script>
function firstLoad(callback) { //secondLoad is "saved" in the callback variable
console.log("firstLoad function fired.");
//When Firstload is done with doing all it has to do you have to manually call
//the callback which references to the secondLoad function:
callback();
}
function secondLoad() {
console.log("secondLoad function fired.");
}
//Here you pass the secondLoad function as a parameter for the firstLoad function,
//in your code you were passing the *result* of secondLoad
firstLoad(secondLoad);
</script>
</body>
</html>
I am assuming that firstLoad is not doing asynchronous stuff like network requests
Upvotes: 2
Reputation: 370819
Expressions in an argument list are evaluated immediately, so that the expression can be passed to the function. So with
firstLoad(secondLoad());
secondLoad
is called and evaluated to
firstLoad(undefined);
before firstLoad
is called.
If firstLoad
is asynchronous, pass just the secondLoad
function name instead, and call it as a callback at the end of the asynchronous action:
function firstLoad(callback) {
console.log("firstLoad function fired.");
setTimeout(() => {
console.log('firstload done');
callback();
}, 1000);
}
function secondLoad() {
console.log("secondLoad function fired.");
}
firstLoad(secondLoad);
You can also have firstLoad
return a Promise:
function firstLoad() {
console.log("firstLoad function fired.");
return new Promise((resolve) => {
setTimeout(() => {
console.log('firstload done');
resolve();
}, 1000);
});
}
function secondLoad() {
console.log("secondLoad function fired.");
}
firstLoad()
.then(secondLoad);
Of course, if firstLoad
isn't asynchronous, just call secondLoad
after firstLoad
:
function firstLoad(callback) {
console.log("firstLoad function fired.");
}
function secondLoad() {
console.log("secondLoad function fired.");
}
firstLoad();
secondLoad();
Upvotes: 1