I've been doing a lot of reading online trying to figure out how to write asynchronous JavaScript code. One of the techniques that has come up a lot in my research is to use callbacks. While I understand the process of how to write and execute a callback function, I'm confused why callbacks seem to automagically make the JavaScript execution asynchronous. So, my question is: how does adding in callback functions to my JavaScript code make said code automagically async?
-
2You might be interested in reading how the browser achieves this within a single thread, written by John Resig: ejohn.org/blog/how-javascript-timers-work– JalaynApr 10, 2013 at 17:05
-
@Jalayn. Thanks. Your comment made all the difference after reading the several answers.– HalfWebDevDec 15, 2015 at 3:13
3 Answers
It doesn't. Just taking a callback or passing a callback doesn't mean it's asynchronous.
For example, the .forEach
function takes a callback but is synchronous.
var available = false;
[1,2,3].forEach( function(){
available = true;
});
//code here runs after the whole .forEach has run,
//so available === true here
The setTimeout
takes a callback too and is asynchronous.
function myFunction( fn ) {
setTimeout( function() {
fn(1,2,3);
}, 0 );
}
var available = false;
myFunction( function() {
available = true;
});
//available is never true here
Hooking to any asynchronous event in Javascript always requires a callback but that doesn't mean calling functions or passing them around is always asynchronous.
-
2@SteveEvers I guess you could edit the MDN article then. Callback is a very common term in javascript for any function passed to another that calls you back using the function you gave... why complicate it? Edit: Callback is also used in specs– EsailijaApr 10, 2013 at 18:52
-
3@SteveEvers "callback implies asyncrony" is a C#/Microsoft idiosyncrasy. en.wikipedia.org/wiki/Callback_(computer_programming)– EsailijaApr 10, 2013 at 18:58
-
1
-
1But that being said @SteveEvers is also wrong. Callbacks don't imply asynchrony, just that someone else will be responsible for "calling back". Apr 10, 2013 at 19:34
-
2I think there's a strong argument for not calling a forEach function a callback. "Here, use this to process a bunch of crap in an array and give me the result. I'll wait for it." is different than, "When you're done, use this for whatever results you got as I will be elsewhere making a sandwich or something." May 4, 2016 at 18:28
The secret of the "magic" is that the events that you are assigning the callbacks to are asynchronous. They're implemented "under the hood" to take care of whatever they're doing (such as retrieving something from a remote server) in the background, outside of the JS sandbox. And then once they're done with their work, they give the JS engine a message to call an event. When the JS engine is finished with whatever it's currently doing, it will call any events that are queued up (or wait for a new message) and then your callback is "magically" invoked asynchronously!
(NOTE: This is a very high-level, conceptual overview of the topic that doesn't go into details, because different JS engines are going to implement things in different ways. But this is the general idea of how it works.)
-
1Which events are these? An example of one or two such events would make your answer even better.– Jo SmoNov 22, 2016 at 7:14
Note: It's a late answer, I just don't think the answers above answer it well. Please google the terms in quotes if you don't understand them.
Tl;dr The right question to ask is what can make something asynchronous. It's not the callbacks that make something asynchronous. I can have function pointers to do the same thing in C, C++ but that does not make it asynchronous. It's the "event loop" that's peculiar about JS and makes it asynchronous.
What you need to understand is what creates this asynchronicity possible. There are 3 things that you can look up for the start which are "coroutines", "fibers", and "interrupts". When JavaScript's "event loop" is executing the code in its pipeline, multiple events created invoke those interrupts and allows the environment to know that something needs to be handled. As long as no one invokes the interrupt handler, the event loop keeps on running.
How to handle it? In this case through callbacks. Are they callbacks automatically called? No, the function you are passing it to needs to call it.
If you see the examples given by @Esailija, setTimeout can generate a timer interrupt, possible to make asynchronous. You can do it synchronous too, keep "polling". Can iteration of a loop possibly generate any interrupt? So, synchronous.
-
This is a really good article on the topic: jakearchibald.com/2015/tasks-microtasks-queues-and-schedules, also this one dev.to/lydiahallie/… Oct 18 at 10:56