J
First of all, we need to understand clearly how the JavaScript event model works. This is fundamental and conditional Totally the operation and the way of working with language. And it's extraordinarily simple:The interpreter DOESN'T MAKE ANYTHING until an event hits it.In his natural state, language is not doing any action. It is limited to waiting, without just consuming CPU time, for an event to happen.All JavaScript function is executed SIN INTERRUPTION until the end.This includes possible calls to other functions. Everything the sequence of actions and calls chains occurs until you reach return of primary functionor an exception (this is the single case in which the return of primary function).To do this, the language is supported by 3 elements:Functions callback.Calls.Match of events.Functions callback:They are but normal and current functions, which are passed as argument to be called later, when necessary.In JavaScript, some types (numbers, strings) are passed by copyothers, more complex (objects, arrays, by reference. Well, a function. callback It's nothing but a reference to a function.Its use is the same as that of any other type of data: to perform actions with it; but, while in an object we can, for example, modify its content, the only action to perform with a function is Call her., doing nombre( ).For example, in setTimeout( mifuncion, 1000 ), we are ♪ as an argument callback: the reference to a function, which will be executed at some future time (approx. 1 second in the future).Here come the game closures (closures in English). To not extend, deny in This model, based on events and reactions to them, it's very, Very. common in the programming of graphic environments, in practice any language.Also, this model presents an inconvenience: event processing Stop. until the execution of the current JavaScript code is completed. That's why disallowing use of functions synchronous: the browser can do nothing (except keep keeping events in the queue) while the JavaScript code is running. And since that code is waiting for the return from a synchronous functionYou will not be able to finish until you get the result of that function. Result: the browser It's blocked.In return, they are used very few resources in times of inactivity (which will be a majority), and eliminates problems of concurrent access to shared data: There is no concept hilosand It's safe. that 2 functions will not be executed at the same time.JavaScriptWith what we have seen before, we conclude that JavaScript is a completely like that. or liabilities: it is not possible to wait until something happens, but that something, when it happens, will warn us.There are, however, some exceptions. The most widely known: requests XMLHttpRequest synchronous.Operative Systems typically provide 2 forms of network access: synchronous and asynchronous. In the first form, the program makes a request and delega in the operating system until this is done. During that time, the programme remains asleep.. The Operating System marks it as on holdAnd he doesn't waste his time with him until the application is over. At that time, it marks it as Ready. and continue its execution.This makes sense in some types of programs, which simply have nothing to do until some action is completed. By marking them as on hold, the Operating System optimizes resources, providing more time to other programs.This way of working is nefarious in JavaScript. The synchronous version XMLHttpRequestcertainly, block totally the current tab, including event management. For practical purposes, the tab remains dead. until the operation is completed.The synchronous version XMLHttpRequest must be avoided at all costs; really, in WEB applications, There's no reason to use it.Returning to the questionApplying the whole Parrafada before the problem, the model to follow is very simple: we wait to get the data, and then.We do all the outstanding actions.We can use an approximation classic:function obtenerLosDatos( url, callback ) {
var xhr = new XMLHttpRequest( );
// Establecemos la REACCIÓN cuando cambie el estado de la solicitud.
xhr.onreadystatechange( stateChanged );
// Lanzamos la ACCIÓN.
xhr.open( 'GET', url );
xhr.send( );
// REACCIÓN
function stateChanged( ) {
try {
if( xhr.readyState == 4 ) callback( xhr.state, JSON.parse( xhr.responseText ) );
} catch( err ) {
callback( xhr.state, undefined );
}
}
}
function PedirDatosYHacerAlgo( ) {
var url = 'http://example.com/data.json';
obtenerLosDatos( url, funcionReaccion );
function funcionReaccion( state, jsonData ) {
// Recibimos el estado, por lo que podemos comprobar posibles errores.
if( state != 200 ) {
alert( 'ERROR !!' );
return;
}
// Comprobamos el JSON recibido.
if( jsonData === undefined ) {
alert( 'BAD JSON' );
return;
}
// Aquí tratamos los datos y hacemos lo que tengamos que hacer con ellos.
...
}
}
Special casesAs we said, the browser it's blocked. while running our JavaScript code; in view of this, it is possible that, on certain occasions, we have to perform processes that take a long time, making our application, in the face of the user She's getting caught.. Next code block totally the active weight for a good time:function ProcesoMuyLargo( ) {
for( let idx = 0; idx < Number.MAX_SAFE_INTEGER; ++idx );
}
ProcesoMuyLargo( );
For these cases, JavaScript provides a very useful function: setTimeout( ).setTimeout( exp, time ):Evaluate the expression exp a certain number of milliseconds passed.The trick It's happening. time value 0. This place the event at the end of the event queue. That is, the browser processes the pending events and, when it comes to ours, He'll return the execution.. This can be used for leave the tab receptive, although we are in very long processes:function ProcesoMuyLargo( ) {
var idx = 0;
function Subproceso( ) {
for( ; idx < Number.MAX_SAFE_INTEGER; ++idx ) {
if( !( idx % 10000 ) ) {
setTimeout( Subproceso, 0 );
return;
}
}
}
}
ProcesoMuyLargo( );
Number used, 10000It's completely arbitrary. The bigger, less it will take the loop to end, but the browser will become more vago to user actions. The smaller the browser responds before actions, but the loop It'll take longer. to complete.