Travailler correctement avec les requêtes Ajax dans WordPress
Chaque fois que vous travaillez avec des API tierces, et que vous le faites de manière asynchrone, il y a toujours le risque que ce que vous demandez renverra un résultat indésirable.
Peut-être s’agit-il d’un code d’erreur, peut-être d’un avertissement, ou peut-être d’un simple message disant quelque chose comme "Nous traitons toujours votre demande de notre côté".
Dans chaque cas, vous pouvez généralement les gérer correctement côté serveur et indiquer au côté client comment le gérer. Mais si vous avez affaire à ce dernier cas, c’est là que vous êtes bloqué par le traitement tiers ; il y a d’autres choses que vous pouvez faire pour mieux gérer cette situation.
Par exemple, dans ce dernier cas, il vaut mieux attendre un peu puis refaire la requête pour voir si l’API a une réponse différente pour vous.
Mais ce faisant, il nécessite Ajax qui nécessite évidemment JavaScript. L’une des méthodes évidentes, mais plus datées, consiste à utiliser setInterval.
Le problème avec cela, cependant, est qu’il crée une pile de requêtes, puis, lorsque la réponse est prête, chaque élément de la pile recevra la même réponse.
Cela peut avoir un impact considérable sur n’importe quel serveur donné. Et il existe de meilleures façons de procéder.
Travailler correctement avec les requêtes Ajax
Comme d’habitude, puisque WordPress est livré avec jQuery, je vais l’utiliser ; cependant, je vous invite également – si vous ne l’avez pas déjà fait – à regarder Ajax dans ES6 pour avoir une idée de la façon de le faire de manière native.
Quoi qu’il en soit, l’idée est la suivante : plutôt que de définir un intervalle, utilisez les fonctions Ajax intégrées pour évaluer correctement la réponse. Et seulement sous certaines conditions, relancez la fonction.
Exemple: la méthode $.post de jQuery offre certaines fonctions qui peuvent être utilisées exactement pour cela. Par exemple, il propose des méthodes telles que :
- Fini()
- échouer()
- toujours()
Et chacun de ceux-ci est destiné à être exécuté sous certaines conditions dont je montrerai momentanément quelques exemples de code.
Avant de faire cela, cependant, il est important de comprendre qu’il y a plusieurs paramètres que j’envoie et que je suppose que vous connaissez :
- l’URL WordPress Ajax (que je définirai comme acme.ajax_url),
- une URL vers la publication que nous consultons (qui sera stockée dans une variable sUrl),
- et un nonce de sécurité que j’appellerai acme.security
Si l’un des éléments ci-dessus n’est pas clair, veuillez lire les pages liées pour voir comment cela est réalisé.
Mais cela dit, voici l’idée derrière la façon dont vous pouvez gérer les réponses Ajax répétées sans setInterval.
1 Une fonction pour le travail
La première chose que vous devez faire est d’envelopper le travail que vous allez faire dans sa propre fonction. Cela signifie que vous pouvez l’appeler de n’importe où ailleurs dans l’application côté client ou même dans le contexte d’une minuterie (si absolument nécessaire).
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() {
// ..
});
}
Et, comme vous pouvez le voir, j’ai avancé et supprimé certaines des fonctions que j’ai mentionnées ci-dessus.
2 Gérer le succès
En cas de succès, vous pouvez utiliser une fonction anonyme comme rappel pour la fonction $.post. L’argument principal dont vous devriez vous préoccuper est l’ argument de réponse .
En règle générale, j’aime que mes réponses aient un attribut de réussite et un attribut d’ échec. Cela facilite la gestion d’un cas chaque fois que la réponse est complètement réussie, mais que les données renvoyées par le serveur ne correspondent pas à ce que j’attendais.
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() {
// ...
});
}
Cela ne signifie pas nécessairement qu’il y a eu un échec. Cela signifie simplement que tout ce que je cherchais à récupérer n’a pas été trouvé.
3 Gérer l’échec
D’un autre côté, il y a des moments où quelque chose peut échouer. La raison pour laquelle cela se produit peut être pour un certain nombre de raisons et pour bien le comprendre, il vaut la peine d’inspecter les arguments fournis par le rappel, à savoir le status et le 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() {
// ...
});
}
Je ne peux pas donner d’exemples concrets ici car chaque API est différente ; Cependant, je recommande au moins d’écrire des données sur la console afin que vous puissiez comprendre ce qui se passe et comment vous pouvez le gérer avec élégance au niveau du code.
4 Gérer le cas inconditionnel
Dans ce cas particulier, cette fonction se déclenchera, que quelque chose ait réussi ou non.
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.
});
}
Cette fonction n’est pas quelque chose dont vous pourriez toujours avoir besoin (sans jeu de mots), mais c’est une option solide pour, par exemple, masquer une barre de progression ou afficher quelque chose sur l’interface utilisateur. Cela peut donner à l’utilisateur un retour indiquant que la requête a terminé son travail (encore une fois, indépendamment de l’échec ou du succès).
5 Gérez le succès, encore une fois
Enfin, la méthode done ressemble beaucoup à la méthode success mais considérez-la comme étant destinée à être appelée une seconde fois.
Cela signifie qu’après le retour de la réponse du serveur avec l’ argument de réponse, la même chose se déclenchera à nouveau une fois que tout le reste sera terminé.
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.
});
}
Cela vous donne une autre chance de faire tout ce que vous voulez faire avec l’argument de réponse une fois de plus avant que tout ne soit terminé.
Je l’utilise rarement, mais il y a eu des moments où j’ai voulu supprimer un élément uniquement après que quelque chose a été fait, tous les autres traitements ont été effectués et la réponse a réussi.
De toute évidence, une grande partie du code ci-dessus est juste pour une démonstration sur la façon de gérer les demandes. Mais le but est de montrer comment gérer ladite requête sans avoir besoin de définir des intervalles pour empiler les requêtes. Au lieu de cela, vous tirez parti des fonctions préexistantes pour, par exemple, appeler à nouveau la fonction en cas d’erreur.
Quoi qu’il en soit, cela peut être exagéré pour certains, mais pour d’autres qui ont l’habitude d’utiliser setInterval, cela peut être une bien meilleure façon de gérer les requêtes Ajax qui ne s’empilent pas et déclenchent la même requête au serveur lorsqu’une réponse a déjà été géré.
Et finalement, c’est l’objectif : un code efficace qui récupère les informations dont nous avons besoin sans enliser l’API tierce ou le navigateur de notre propre utilisateur.
