I am trying to wrap my head around callbacks and I do not understand how callbacks guarantee that a statement will execute after(in terms of time)
Callbacks is a way of invoking a function that is passed as a parameter to invoker function(in your example foo
). Callbacks guarantee that a function will be invoked if no error occurs before it's call inside the function. Callbacks aren't asynchronous either but the way it executes later inside the function after some line of code makes everyone think it as asynchonous at first.
And as you've added setTimeout
function on the above example, setTimeout
is an asynchronous callback envoker function that calls it's callback(in your code () => console.log("Do something with unknown time")
) asynchronously after a certain defined time(2000
). So, setTimeout
wont stop the execution for 2 seconds as you've expected, instead it let's the further line of codes execute without worrying about what will happen inside it's callback. So, the callback()
will trigger at that instant when foo(callback);
is triggered.
You can find more info about callback in here.
If I understand you mean correctly, you can use callback as an event to do something, such as: onerror, oncomplete...
In this example, we start to run todo
function, and we have oncomplete
function which can be used as callback to do something after completing works on todo
function.
While running, if there is some error, it will be logged to onerror
function.
function todo(oncomplete, onerror) {
try {
console.log("Start...");
console.log("Do something with unknown time");
setTimeout(() => oncomplete(),2000);
// you can try to throw error here to test
// throw new Error("Some error message...");
} catch (e) {
onerror(e);
}
}
function oncomplete() {
console.log("Done!");
}
function onerror(e) {
console.error(e.message);
}
todo(oncomplete, onerror);
You have asked two questions,
Is callback execution sequence guaranteed?
Is callback only respond to events ?
From my understanding, callback
is just calling another function to be run now (when it is called)
It is guarantee to run immediately when you call it.
To ensure something is called before the callback is triggered, simply put the things you want to call execute first before callback is conducted.
e.g. from your code, by modify it a bit, callback is guarantee to run after the console.log is executed.
function foo(callback) {
setTimeout(() => {
console.log("Do something with unknown time");
callback();
}, 2000);
}
function callback() {
console.log("Execute callback");
}
foo(callback);
It is the setTimeout
which defers the execution, and is not related to callback methodology.
elem.addEventListener("click", callback);
. But not only that. A simple example will be illustrated below.
e.g.
var map = function(arr, callback) {
var result = [];
for (var i = 0, len = arr.length; i < len; i++) {
result.push(callback(arr[i]));
}
return result;
};
map([0, 1, 2, 3], function(item) {
return item * 2;
})
This edit is referring to
For example, if I am making a database call, I do not know how much time it is going to take for the data to be retrieved. If i try to access it before it has arrived, I'll get an error.
Calling a database, is by no means different from an async http request. So here, I will use XMLHttpRequest to demonstrate how to use callback to ensure this. But normally, these are features provided in browser or node.js already. So you do not need to write it by your own. Of course, to prevent callback hell, I will personally prefer use of Promise
or async/await
. But this is a bit out of topic.
So let see how XMLHttpRequest can use callback to handle async task.
var sendRequest = function(callback) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
callback(this);
}
};
xhttp.open("GET", "filename", true);
xhttp.send();
}
and you can use callback to handle async event. Sometime you dont know when it will happen. And the basic idea how it works is from the example I have said in answer 1.