Problème ajax pour Chrome et Safari avec async: false

J’ai vu cela partout sur le Web, mais je ne parvenais pas à corriger mon code pour éviter ce problème. J’ai simplement une fonction ajax que je déclenche lorsque l’on clique sur certains boutons. non, alors je construis ma fonction:

function doAjax(action, todo, items, error_num, hide_indicator) { items.action = action; items.do = todo; var postedObj; $.ajax({ type: 'post', dataType: 'html', url: ajaxURL, data: items, async: false, beforeSend: function() { if (!hide_indicator) showIndicator(); }, success: function(data) { if (data) { ajaxObj = JSON.parse(data); if (ajaxObj.ok) { postedObj = ajaxObj; } else { alert(ajaxObj.error); postedObj = false; } } else { alert('[' + error_num + '] Something went wrong.'); postedObj = false; } if (!hide_indicator) hideIndicator(); }, error: function() { alert('[' + error_num + '] Something went wrong.'); postedObj = false; if (!hide_indicator) hideIndicator(); } }); return postedObj; } 

Et voici ce que je fais sur mes boutons pour appeler la fonction:

 $(document).on('click', '.ad-single', function() { var addataObj = doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false); // false means DON'T hide the indicator if (addataObj) { loadContent(addataObj.ad); } }); 

OK, pour l’instant, tout fonctionne comme prévu sur Firefox. Lorsque je clique sur mon bouton, l’indicateur s’affiche et attend que les données soient renvoyées par ajax, puis masque à nouveau l’indicateur.

Cela ne fonctionne pas sous Chrome et Safari, la fonction fonctionne correctement et renvoie les données comme prévu, mais il semble que la fonction hideIndicator() soit appelée immédiatement. Je ne savais pas comment résoudre ce problème.

Firefox:

entrez la description de l'image ici

Chrome et Safari:

entrez la description de l'image ici

Utiliser async: false c’est mal. Internet regorge de messages de ce type, et de nombreux navigateurs, y compris Chrome et Safari, vous avertiront de nombreuses requêtes AJAX synchrones.

Heureusement, les promesses de jQuery peuvent être utilisées pour résoudre votre problème. Cela ne change pas le fonctionnement de votre fonction et exploite la puissance des promesses pour faire des requêtes asynchrones.

Vous pouvez modifier votre fonction existante comme suit, de sorte qu’elle renvoie une promesse AJAX au lieu du résultat.

 function doAjax(action, todo, items, error_num, hide_indicator) { items.action = action; items.do = todo; return $.ajax({ type: 'post', dataType: 'html', url: ajaxURL, data: items, beforeSend: function() { if (!hide_indicator) showIndicator(); } }) .then(function(data) { if (!hide_indicator) { hideIndicator(); } if (data) { ajaxObj = JSON.parse(data); if (ajaxObj.ok) { return ajaxObj; } alert(ajaxObj.error); return false; } alert('[' + error_num + '] Something went wrong.'); return false; }, function() { if (!hide_indicator) { hideIndicator(); } alert('[' + error_num + '] Something went wrong.'); return false; }); } 

Ici, une fonction .then peut être utilisée pour prétraiter la réponse et renvoyer la valeur appropriée aux gestionnaires de promesses suivants.

Un gestionnaire de promesse ultérieur peut être implémenté comme suit, appelant la fonction doAjax et réagissant aux retours de valeur par prétraitement.

 $(document).on('click', '.ad-single', function() { doAjax('post_requests', 'get-ad-info', {"id": $(this).data('ad')}, '158', false) .then(function(addataObj) { if (addataObj) { loadContent(addataObj.ad); } }); }); 

Ici, le .then() enchaîne avec le précédent .then() et réagit sur la valeur renvoyée (qui est reçue dans addataObj ). Notez qu’il ne réagit que sur le succès de l’appel AJAX. Si vous souhaitez également gérer la réponse d’erreur, vous devez transmettre un deuxième argument en tant que fonction au gestionnaire .then() .

J’espère que ceci résoudra votre problème.