Con este título la gente de IBM nos muestra un artículo bastante interesante en el que vemos una forma muy interesante de hacer nuestras llamadas asincronas mediante javascript (Ajax), principalmente se trata de una función que como veremos más adelante inteta cubrir todos los flancos que pueden hacer fallar la experiencia asincrona.
Función propuesta completa
function getResource(uri, data_callback, error_callback, timeout) {
var tryAgain = function () {
getResource(uri, data_callback, error_callback, timeout);
}
var r = new XMLHttpRequest();
var timer = setTimeout(
function() {
r.abort();
r.onreadystatechange = null;
setTimeout(tryAgain, timeout);
},
timeout);
r.open("GET", uri, true);
r.onreadystatechange = function() {
if (r.readyState != 4) {
return;
}
clearTimeout(timer); // readyState==4, borramos timer
if (r.status==200) { // "OK status"
data_callback(r.responseText);
}
else if (r.status==304) {
// "Not Modified": No modificamos la salida
}
else if (r.status >= 400 && r.status < 500) {
// Posible error, posible URI erronea
error_callback(r)
}
else if (r.status >= 500 && r.status < 600) {
// Server error, volvemos a lanzar con un poco de demora
setTimeout(tryAgain, timeout);
}
else {
error_callback(r);
}
}
r.send(null);
return r;
}
Función detallada
Empezando de arriba a abajo, tenemos la variable tryAgain
, que no es más que la definición de una función que hace la misma llamada que hemos hecho inicialmente. Esta variable será usada para lanzar la función en caso de necesitar relanzarla por algún motivo.
var tryAgain = function () {
getResource(uri, data_callback, error_callback, timeout);
}
Sobre la variable r
, recae la responsabilidad de albergar el objeto XMLHttpRequest()
que hará posible el asincronismo. Aunque yo propongo algo más completo para asegurarnos que IE6 no se quede fuera de juego.
var r = new XMLHttpRequest();
//Más completo
var r = (XMLHttpRequest)?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
Ya con el objeto principal cargado, declaramos la variable timer
, que al igual que tryAgain
solo será llamada en el caso en se requiera. Esta función se encargará abortar la transacción asíncrona al cubrir el tiempo timeout
dado.
var timer = setTimeout(
function() {
r.abort();
r.onreadystatechange = null;
setTimeout(tryAgain, timeout);
},
timeout);
Una vez preparado el camino con las variables necesarias para el funcionamineto, solo nos queda hacer la llamada, en este caso por GET
, y controlar los valores retornados para accionar una funcionalidad u otra.
Tratando la respuesta
Al igual que en el ejemplo anterior, la respuesta tambien debería ser tratada teniendo en cuenta un timeout que nos evitará demoras innecesarias. Para ello definiremos nuestra función usando una estructura similar a esta.
var other_data = null;
function processData(this_data) {
var delay = 1000; // Esperamos 1 segundo
if (other_data == null) {
setTimeout(function() { processData(this_data); }, delay);
return;
}
// Tenemos this_data y other_data
displayThisAndThat(this_data, other_data);
// Reseteamos other_data, ya la hemos usado
other_data = null;
}
// Ejemplo de uso
getResource(uri2,processData,errorData, 5000);
2 comentarios, 1 referencias
+
#