Bonjour à tous,
Je recontre un petit problème sans gravité, mais pas pratique.

J'explique la situation :
Je dois lancer des requêtes AJAX sur base d'un $.each() en jquery.

Le problème :
Le code boucle bien tout, mais du coup lance toutes mes requêtes AJAX en parallèle.
En ajoutant "async: false" dans la fonction .ajax => cela fait mieux le travail mais le contenu de "beforeSend" et de "success" ne s'affichent à l'écran que APRES toutes les requêtes AJAX.
Or je souhaiterais ajouter un progressbar => qui n'aurait aucun sens dans la situation actuelle.

$("#api-send-start").click(function(){
    $("table tbody tr[data-id]").each(function(){
        ajaxApi($(this), $(this).data('id'));
    });
});

function ajaxApi (element, id) {
    let lastTD = element.find('td:last');
    $.ajax({
        //async: false,
        url: Routing.generate('superAdmin_fwbApi_setUser', {id: id}),
        beforeSend: function() {
            lastTD.html('EN COURS !!!');
        },
        success : function(response) {
            console.log(response);
            lastTD.html(response.idEsahr);
        }
    })
}

Je voudrais :
Lors que je lance l'opération décrite en code ci-dessous, étape par étape cela devrait donner :

  1. Lire le 1er item
  2. Préparer le resuête AJAX
  3. Exéctuer la fonction "beforeSend" => changement du contenu texte d'un TD
  4. Effectuer la requête AJAX
  5. si c'est "success" => changement du contenu texte d'un TD ET (à l'avenir) modifier la progressbar.
  6. Lire l'item suivant et on recommence au point 2.

Si l'un d'entre vous aurait la petite solution miracle pour que tout se fasse au fur et à mesure (et non une fois que tout est fini) ce serait bien gentil !!!

Merci pour votre aide précieuse !!!

6 réponses


popotte
Réponse acceptée

Hello :)

Alors pour ne pas faire de paralèle faut faire une fonction async, et faire un await pour dire à JS que tu veux attendre la fin d'un process avant de continuer

async function ajaxApi (element, id) {
    let lastTD = element.find('td:last');
    await $.ajax({
        async: true, // tant qu'a faire
        url: Routing.generate('superAdmin_fwbApi_setUser', {id: id}),
        beforeSend: function() {
            lastTD.html('EN COURS !!!');
        },
        success : function(response) {
            console.log(response);
            lastTD.html(response.idEsahr);
        }
    })
}
jojo1084
Auteur
Réponse acceptée

Pourquoi les envoyer 1 à 1 ?
Le webservice avec le quel je corresponds ne permet que de le faire à l'unité (je sais c'est absurde... mais bon...)
En attendant, j'ai résolu mon problème avec une boucle for et un "await fetch".
LE problème est donc résolu.
Merci pour vos réponses.

Salut.

Plusieurs trucs me viennent en lisant ta question :

  1. pourquoi ne pas envoyer tous les IDs d'un coup ? Si tu fais la même chose pour chaque id envoyé alors ça vaut le coup de tout grouper.
  2. Sinon si tu veux garder une requête par ID alors je ne pense pas que ce soit une mauvaise chose que ce soit en parallèle. La barre de progression peut être mise à jour dans chaque success.
  3. micro opti : mettre en cache $(this) :
    const $this = $(this);
    ajaxApi($this, $this.data('id'));
jojo1084
Auteur

Merci bcp. "await" a résolu mon problème.
A bientôt.

Await à peut-être résolu ton problème, mais la problématique n'est pas la bonne.

On ne lance pas les requêtes les unes à la suites des autres parceque tu veux une barre de progression. La solution de @JoolsMcFly répond plus à la problématique.

Tout à fait.

Si t'as 15 éléments dans ta page alors tu vas faire 15 aller/retour avec le serveur qui va donc :

  1. vérifier que t'es bien connecté (1 requête pour choper ton mdp)
  2. mettre à jour tes infos de dernière connection en base (1 requête de mise à jour)
  3. faire le traitement et faire une ou plusieurs requêtes en base.
  4. potentiellement d'autres traitements

et ce x15.
Si t'as de la latence réseau et bien tu l'as 15 fois.
Autrement dit en faisant en une seule fois t'as 15 fois moins de latence. ^^