The largest Javascript process is consider a single event. If you perform a long operation within this event the process may lock for a few moments the browser (or other software that uses Ecmascript), then the process will stop processing other events until it completes its operation and will probably freeze the browser.
For example if you use XMLHttpRequest
in this way:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url_arquivo_grande', false); //false = síncrono
xhr.send(null);
alert(xhr.responseText);
alert('Outra tarefa...');//Isto iria demorar de aparecer e provavelmente o navegador irá congelar
The main process of the browser will stay locked until the server has finished sending the response to the client and the client (client in the case of the browser) process this response.
Therefore in XMLHttpRequest
we used to use AJAX
(Asynchronous Javascript and XML) which would be the asynchronous way of it, which would be something like:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url_arquivo_grande', true); //true = assincrono
xhr.onreadystachange = function () { alert(xhr.responseText); };
xhr.send(null);
alert('Outra tarefa...');//Isto não espera o ajax
You don’t need to use callback
for everything, but if your code has a great chance to block/freeze other operations it is essential that you use asynchronous methods, or even setTimeout
.
Which really brings us to callback
If the code is delayed (even if it is not XMLHttpRequest
), worth you resort to a setTimeout
, from this moment you nay will be able to use the return ...
, then it will be necessary to use the callback
.
But it’s like I said, there’s no need to use callback at all, just where asynchronous events will be required.
Example of need 1:
In this example below we will try to use return
, but when we use setTimeout
, the return
finish the process before the setTimeout
, in other words the return
will return 0
, only after a millisecond the variable will be with the value 1
, however return
was sued before this:
function test() {
var a = 0;
setTimeout(function() {
//Código demorado
a = 1;
//Código demorado
}, 1);
return a;
}
console.log(test());//Irá retornar 0
With callback it is possible to capture the response of an "asynchronous event":
function test(callback) {
var a = 0;
setTimeout(function() {
//Código demorado
a = 1;
//Código demorado
callback(a);
}, 1);
}
test(function (response) {
console.log(response);//Irá retornar "1"
});
Example of necessity 2:
In the following example I used XMLHttpRequest
asynchronous because it prevents freezing, but I tried to capture responseText
, but since the answer is not yet ready the result will be an "empty string", null
or undefined
.
function ajax() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url_arquivo_grande', true);
xhr.send(null);
return xhr.responseText;
}
console.log(ajax());//Irá retornar null ou undefined
But if we use onreadystatechange
, we can wait for the server response, but it will not be possible to use return
, because it event is in another cycle/following or is it asynchronous, as in the example:
function ajax() {
var data = null;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url_arquivo_grande', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status === 200) {
data = xhr.responseText;
}
}
};
xhr.send(null);
return data;
}
console.log(ajax());//Irá retornar null
So the solution is to use callback:
function ajax(callback) {
var data = null;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url_arquivo_grande', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status === 200) {
callback(xhr.responseText);
}
}
};
xhr.send(null);
}
test(function (response) {
console.log(response);//Irá retornar "1"
});
Note, just because we have one setTimeout
, does not mean that it will be warranty against "crashes", so it follows a list of technologies developed to make the user experience better:
Note that Node.js is an asynchronous "server", unlike Apache which is synchronous. The probability of asynchronous servers performing better is very high and for this reason it is so "rated".
Asynchronous to synchronous difference:
As explained earlier, the reason for using callback in particular is because of asynchronous events, but if it was not possible to understand what is ASYNCHRONOUS, see an example of the difference between "synchrony" and "asynchronous" and why we cannot use asynchronous with return
:
The first (synchronous) drawing illustrates that a=1;
is in line and return a;
will only be executed after a=1;
, the disadvantage and if a=1;
is a time-consuming process, so this can slow down the main process, if it doesn’t slow down, then yes you can use synchronous.
The image illustrates that the a=1;
is in an asynchronous event (can be ajax, setTimeout
, or other types), see that a=1;
was only delivered after the return a;
, so this return runs first and does not bring the necessary response, in the example it will bring the value 0
instead of 1
, then in this case it will be necessary the "callback".
Why
-2
in this question?– Sergio
As in "no callback", both examples have "callback"? I’m not the one who said no, but I suppose that’s why. Note: Callback is something that is in the "soul" of Ecmascript codes, not working with Callback in it is the same as "limit" almost all its functionalities, in other words, it is not a matter of head start, is how the language works in most javascript codes. Note 2: Both of your examples use callback, you just couldn’t figure it out.
– Guilherme Nascimento
@Sergio is, I didn’t understand it either. Maybe they thought the title referred to two different subjects... in the end...
– ropbla9
Maybe you’re ignoring my comment friend, but I’m just saying this: As far as you think you didn’t apply callback, you applied, you just didn’t notice. That inside the
setTimeout
in the two examples are "callbacks". So the first example has 2 callbacks, the second only one callback.– Guilherme Nascimento
@Guilhermenascimento, I know I applied callback to
setTimeout
but the question is to present the "structure" made by me and not thesetTimeout
. I should have taken him away...– ropbla9
@ropbla9 That way you worked is useful when code works in an ASYNCHRONOUS way, thus avoiding engine freezing, almost everything in Ecmascript is preferable to work asynchronously, so one execution won’t have to wait for the other to respond and the two of you can work side by side. Note: In a code that does a great routine and takes some time, this can prevent other codes from having to wait for it to end (of course you have to know how to implement this).
– Guilherme Nascimento
@Guillhermenascimento, could you write me an answer?
– ropbla9
This my answer maybe it’ll help you.
– bfavaretto