Trabajar correctamente con solicitudes Ajax en WordPress
Siempre que trabaje con API de terceros, y lo haga de forma asíncrona, siempre existe la posibilidad de que lo que sea que esté solicitando devuelva un resultado no deseado.
Tal vez sea un código de error, tal vez sea una advertencia, o tal vez sea un mensaje simple que dice algo como "Todavía estamos procesando su solicitud por nuestra parte".
En cada caso, generalmente puede manejarlos bien en el lado del servidor y dejar que el lado del cliente sepa cómo manejarlo. Pero si está lidiando con el último caso, ahí es donde está bloqueado por el procesamiento de terceros; hay otras cosas que puede hacer para manejar mejor esta situación.
Por ejemplo, en el último caso, es mejor esperar un poco y luego volver a realizar la solicitud para ver si la API tiene una respuesta diferente para usted.
Pero al hacer esto, requiere Ajax que obviamente requiere JavaScript. Uno de los métodos obvios, aunque más anticuados, para hacer esto es usar setInterval.
Sin embargo, el problema con esto es que crea una pila de solicitudes y luego, cuando la respuesta está lista, cada elemento de la pila obtendrá la misma respuesta.
Esto puede afectar drásticamente a cualquier servidor dado. Y hay mejores maneras de hacer esto.
Trabajar correctamente con solicitudes Ajax
Como de costumbre, dado que WordPress viene con jQuery, lo usaré; sin embargo, también lo insto, si aún no lo ha hecho, a mirar Ajax en ES6 para tener una idea de cómo hacer esto de forma nativa.
De todos modos, la idea es esta: en lugar de configurar un intervalo, utilice las funciones integradas de Ajax para evaluar la respuesta correctamente. Y solo bajo ciertas condiciones, active la función nuevamente.
Caso en cuestión: el método $.post de jQuery ofrece algunas funciones que se pueden usar exactamente para esto. Por ejemplo, ofrece métodos como:
- hecho()
- fallar()
- siempre()
Y cada uno de estos está destinado a ejecutarse bajo ciertas condiciones, de las cuales mostraré en algunos ejemplos de código momentáneamente.
Sin embargo, antes de hacer eso, es importante comprender que hay varios parámetros que estoy enviando y que asumo te resultarán familiares:
- la URL de WordPress Ajax (que definiré como acme.ajax_url),
- una URL a la publicación que estamos viendo (que se almacenará en una variable sUrl),
- y un nonce de seguridad al que llamaré acme.security
Si algo de lo anterior no está claro, lea las páginas vinculadas para ver cómo se logra.
Pero dicho esto, esta es la idea detrás de cómo puede administrar las respuestas repetidas de Ajax sin setInterval.
1 Una función para el trabajo
Lo primero que debe hacer es envolver el trabajo que va a realizar en su propia función. Esto significa que puede llamarlo desde cualquier otro lugar en la aplicación del lado del cliente o incluso dentro del contexto de un temporizador (si es absolutamente necesario).
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// ...
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
// ...
})
.always(function() {
// ..
});
}
Y, como puede ver, seguí adelante y eliminé algunas de las funciones que mencioné anteriormente.
2 Manejar el éxito
En caso de éxito, puede utilizar una función anónima como devolución de llamada para la función $.post. El argumento principal con el que debe preocuparse es el argumento de respuesta .
Por lo general, me gusta que mis respuestas tengan un atributo de éxito y un atributo de fracaso. Esto hace que sea más fácil manejar un caso siempre que la respuesta sea completamente exitosa, pero los datos que regresaron del servidor no fueron los que esperaba.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM.
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
// ...
})
.always(function() {
// ...
});
}
Esto no significa necesariamente que hubo una falla. Simplemente significa que lo que sea que estaba buscando recuperar no fue encontrado.
3 Manejar la falla
Por otro lado, hay momentos en los que algo puede fallar. La razón por la que sucede esto puede deberse a varias razones y, para comprenderlo correctamente, vale la pena inspeccionar los argumentos que proporciona la devolución de llamada, es decir, el estado y el error.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM like flashing the first image.
$('img:first').fadeTo('fast', 0.5, function() {
$(this).fadeTo('fast', 1);
});
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
cosole.log(error);
})
.always(function() {
// ...
});
}
No puedo dar ejemplos concretos aquí porque cada API es diferente; sin embargo, recomiendo al menos escribir datos en la consola para que pueda comprender lo que está sucediendo y cómo puede manejarlo correctamente a nivel de código.
4 Manejar el Caso Incondicional
En este caso particular, esta función se activará independientemente de si algo tuvo éxito o no.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM like flashing the first image.
$('img:first').fadeTo('fast', 0.5, function() {
$(this).fadeTo('fast', 1);
});
})
.done(function(response) {
// ...
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
console.log(error);
})
.always(function() {
// Regardless of what happens, this is where you can provide the user feedback.
});
}
Esta función no es algo que siempre pueda necesitar (sin juego de palabras), pero es una opción sólida para, por ejemplo, ocultar una barra de progreso o mostrar algo en la interfaz de usuario. Esto puede brindarle al usuario un poco de información de que la solicitud ha completado su trabajo (nuevamente, independientemente de la falla o el éxito).
5 Manejar el éxito, otra vez
Finalmente, el método done es muy parecido al método success, pero piense que está destinado a ser llamado por segunda vez.
Eso significa que después de que la respuesta haya regresado del servidor con el argumento de respuesta, lo mismo volverá a activarse una vez que todo lo demás se haya completado.
var _processArticle = function() {
var request =
$.post(acme.ajax_url, {
action: 'acme_get_data',
url: sUrl
security: acme.security
}, function(response) {
// Abort all request operations.
if (false === response.success) {
request.abort();
}
// Handle the successful response by modifying the DOM.
})
.done(function(response) {
// Display any additional changes you may want to make based on the respnse.
})
.fail(function(xhr, status, error) {
console.log('There was a problem with contacting the API.');
console.log('The status was:');
console.log(status);
console.log('The error was:')
console.log(error);
})
.always(function() {
// Regardless of what happens, this is where you can provide the user feedback.
});
}
Esto le da otra oportunidad de hacer lo que quiera con el argumento de respuesta una vez más antes de que todo se haya completado.
Raramente uso esto, pero ha habido momentos en los que he querido eliminar un elemento solo después de que se hizo algo, se realizó todo el otro procesamiento y la respuesta fue exitosa.
Tal vez no lo necesites todo
Obviamente, gran parte del código anterior es solo para una demostración sobre cómo manejar las solicitudes. Pero el propósito es mostrar cómo manejar dicha solicitud sin necesidad de establecer intervalos para apilar solicitudes. En su lugar, aprovecha las funciones preexistentes para, por ejemplo, volver a llamar a la función si hay un error.
De todos modos, esto puede ser excesivo para algunos, pero para otros que están acostumbrados a usar setInterval, puede ser una forma mucho mejor de administrar las solicitudes de Ajax que no se acumulan y enviar la misma solicitud al servidor cuando ya se ha recibido una respuesta. administrado.
Y, en última instancia, ese es el objetivo: código eficiente que recupera la información que necesitamos sin atascar la API de terceros o el navegador de nuestro propio usuario.
