I really don't understand... I'm a beginner in Javascript.
I have attached my function onLoadDocument to the document.onload event.
The callback function absolutely have to be executed after function111() and function222() have totally finished their job.
Actually, the callback is executed too soon and it causes a problem to function111 and function222.
How to execute the callback function ONLY when function111 and function222 will have finished their job?
function onLoadDocument(event, callback) {
function111();
function222();
callback();
}
function after() {
firstOpeningWindow = false;
}
document.onload = onLoadDocument(event, after);
The issue is that a callback is a function reference, but this line:
onLoadDocument(event, after)
is a function invocation and therefore runs immediately. Also, it's window that has a load event, not document.
function onLoadDocument(callback) {
function111();
function222();
callback();
}
function after() {
firstOpeningWindow = false;
}
// You have to supply a function reference here. So, to pass arguments
// you'd need to wrap your function invocation in another function that
// will be the callback
window.onload = function() { onLoadDocument(after) };
The problem is that window.onload (as a commenter on another answer said,, document.onload doesn't exist) takes a function, which is executed when the event happens. You're not passing in a function here, you're passing in the return value of onLoadDocument(event, after). This is undefined - and to get that, the browser is executing the function, which is too early for you.
The solution is just to have onLoadDocument return a function:
function onLoadDocument(event, callback) {
return function () {
function111();
function222();
callback();
}
}
function after() {
firstOpeningWindow = false;
}
window.onload = onLoadDocument(event, after);
The function is called when you call the function, so:
document.onload = onLoadDocument(event, after);
… calls onLoadDocument immediately and assigns the return value to onload (which is pointless because the return value is not a function).
If you want to take this approach, then you need to write a factory which generates your onload function using a closure:
function onLoadDocumentFactory(callback) {
function onLoadDocument(event) {
function111();
function222();
callback();
}
return onLoadDocument;
}
function after() {
firstOpeningWindow = false;
}
document.onload = onLoadDocument(after);
That said, it would be easier just to add your functions in order using the modern addEventListener.
function function111() {
console.log(111);
}
function function222() {
console.log(222);
}
function after() {
console.log("after");
}
addEventListener("load", function111);
addEventListener("load", function222);
addEventListener("load", after);
Related
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.
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
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();
So I want to use a callback function within .fadeOut() after it complete's the animation. I can do this successfully using the following, no problem. Works just like I want (The HTML and CSS are just a single black square div)
function fadeOutThing(speed, callback) {
$('div').parent().fadeOut(speed, function() {
if (typeof callback === "function") {
callback();
}
});
}
function OtherThing() {
console.log("hello");
}
fadeOutThing(5000, OtherThing);
What I really want is for that callback function have its own argument, which could be another callback function, like the following. The problem is that when I do this, the log will display before the animation is complete: Here's the fiddle
function fadeOutThing(speed, callback) {
$('div').parent().fadeOut(speed, function() {
if (typeof callback === "function") {
callback();
}
});
}
function OtherThing(stuff) {
console.log("hello" + stuff); //This displays too soon!
}
fadeOutThing(5000, OtherThing(' stuffsss'));
Why is this happening? What am I not understanding?
The issue is because you call OtherThing() immediately on load of the page. This means you're giving the result of the OtherThing() function as the callback parameter, not the reference to the function.
To do what you require you can provide an anonymous function to the callback which wraps your OtherThing() call:
fadeOutThing(5000, function() {
OtherThing(' stuffsss'));
});
Bind the argument instead of calling the function as follows:
fadeOutThing(5000, OtherThing.bind(this,' stuffsss'));
Your are using/calling function in attribute so instead of function declaration you send its return in this case is no return so:
fadeOutThing(5000, OtherThing(' stuffsss'));
equals
fadeOutThing(5000, notDeclaredNothing); //undefined variable
To send function declaration and set paramaters you could do for example third paramater:
function fadeOutThing(speed, callback,attrs) {
$('div').parent().fadeOut(speed, function() {
if (typeof callback === "function") {
callback(attrs); //use with attributes
}
});
}
usage:
fadeOutThing(5000, OtherThing,'stuffsss');
Or second option is to use bind - bind creates new function with given this and given attributes:
fadeOutThing(5000, OtherThing.bind(this,'stuffsss'));
This in global scope is window object.
I'm working on a big project and I simplified what it matters here. This is the code:
a = new Thing(/*sayHi + sayHey*/);
function sayHi() {
alert("hi");
}
function sayHey() {
alert("hey");
}
function Thing (callback) {
callback();
}
I'd like to, with just the callback parameter, call both the sayHi() and the sayHey() function, at the order I put them. Is it possible? How would I do it? Thank you.
Pass an anonymous function that calls both of them sequentially:
a = new Thing(function() {
sayHi();
sayHey();
});
function sayHi() {
alert("hi");
}
function sayHey() {
alert("hey");
}
function Thing (callback) {
callback();
}
Alternatively to #Barnar's answer, create and pass a regular named function. If the callback logic gets heavier, you might want that anyway.
function hiHeyCallback() {
sayHi();
sayHey();
}
a = new Thing(hiHeyCallback);
In Javascript, is there some way to bind and event handler of one function activating and ending?
So, for instance, I have two functions:
function one() { console.log("this is function one") }
and
function two() { console.log("this is function two") }
I want function two to activate both when function one is called and when it ends. Obviously, I could just:
function one() { two(); console.log("this is function one"); two() }
but that'd be boring -- not nearly as interesting as this way.
Well, you could write a function that wraps the original function in another that calls the callback.
function bindStartEnd(originalFn, callback, thisArg) {
return function() {
var returnValue;
callback();
returnValue = originalFn.apply(thisArg || null, arguments);
callback();
return returnValue;
};
}
It could be used like this:
function one() {
console.log("This is function one");
}
function two() {
console.log("This is function two");
}
var three = bindStartEnd(one, two);
three();
And it could be extended to also accept two callbacks, one for the beginning and one for the end. You might also think of a better name.
Ok so lets say I have this function:
function a(message) {
alert(message);
}
And I want to have a callback after the alert window is shown. Something like this:
a("Hi.", function() {});
I'm not sure how to have a callback inside of the function I call like that.
(I'm just using the alert window as an example)
Thanks!
There's no special syntax for callbacks, just pass the callback function and call it inside your function.
function a(message, cb) {
console.log(message); // log to the console of recent Browsers
cb();
}
a("Hi.", function() {
console.log("After hi...");
});
Output:
Hi.
After hi...
You can add a if statement to check whether you add a callback function or not. So you can use the function also without a callback.
function a(message, cb) {
alert(message);
if (typeof cb === "function") {
cb();
}
}
Here is the code that will alert first and then second. I hope this is what you asked.
function basic(callback) {
alert("first...");
var a = "second...";
callback(a);
}
basic(function (abc) {
alert(abc);
});