IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

Requête prioritaire lancée en aval [AJAX]


Sujet :

jQuery

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Juin 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Juin 2012
    Messages : 4
    Par défaut Requête prioritaire lancée en aval
    Bonjour à tous,

    Supposons le code de cochon suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    <button id="btn">Click !</button>
    <div id="content"></div>
     
    <script>
    var data = {};
     
    $(document).ready(function(){
      for(var i=1; i<=20; i++){
        $.ajax({
            type : "GET",
            url : "data.xml",
            data : "id="+i,
            dataType : "text",
            success : function(text) {
                  data[i] = text;
            }
         }
      }
     
      $("#btn").click(function(){
        $.ajax({
            type : "GET",
            url : "data2.xml",
            dataType : "text",
            success : function(text) {
                  $("#content").html(text);
            }
         }
      });
    }
    </script>
    La boucle a pour but de pré-charger un certain nombre de données. De construire un cache 'data'. (L'environnement technique me contraint à utiliser cette méthode plutôt dégueulasse, impossible de charger toutes les infos en une seule requête par exemple)

    Le bouton doit quand à lui charger une autre requête dans la page.

    Nous pouvons tracer le log suivant au chargement de la page :
    Lancement AJAX 0
    Lancement AJAX 1
    Lancement AJAX 2...
    ... Lancement AJAX 19
    Réception AJAX 0
    Réception AJAX 1...
    ...Réception AJAX 19


    Le problème réside dans le fait que même si toutes les requêtes sont envoyées quasi simultanément, les retours sont traités un par un et prennent un peu plus de temps, ils sont comme "mis en queue".

    Si j'affiche la page et clic immédiatement sur le bouton, j'aimerais que le traitement de la requête associée au bouton soit traitée immédiatement.

    Soit :
    Lancement AJAX 0
    Lancement AJAX 1
    Lancement AJAX 2...
    ... Lancement AJAX 19
    Réception AJAX 0
    Réception AJAX 1
    Click sur Bouton
    Réception de Bouton

    Réception AJAX 2
    Réception AJAX 3...
    ...Réception AJAX 19

    Or j'obtiens
    Lancement AJAX 0
    Lancement AJAX 1
    Lancement AJAX 2...
    ... Lancement AJAX 19
    Réception AJAX 0
    Réception AJAX 1
    Click sur Bouton
    Réception AJAX 2
    Réception AJAX 3...
    ...Réception AJAX 19
    Réception de Bouton

    Les résultats sont a peu près traités dans l'ordre d'appel.

    Les appels sont fait en moins d'1ms, les réceptions des résultats durent environ 6sec. Ma réception de bouton peut être faite après les 20 appels, mais pas après les 20 réceptions.

    Des idées ?

  2. #2
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 208
    Par défaut
    Bonjour,
    tu envoies toutes tes requêtes à la queue leu-leu, dans la boucle for, au moment du click sur le bouton la nouvelle requête est soumise en dernier donc, elle reviendra donc après les précédentes.

    Si tu souhaites "hiérarchiser" tes requêtes il te faut les mettre dans une liste et ne traiter la suivante que lorsque celle en cours reviens, ainsi si tu cliques pour un envoi prioritaire il te suffit d'insérer cette demande dans ta liste.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Juin 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur d'études

    Informations forums :
    Inscription : Juin 2012
    Messages : 4
    Par défaut
    Merci pour cette réponse.
    C'est ce que j'ai testé et effectivement ça fonctionne.

    Je partage le code pour les interessés :

    Fichier: ajaxQueue.js
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
     
    var AjaxQueue = function() {
     
        this._reqsQueue = [];
        this._reqsStatuts = [];
        this._traitementStatut = false;         // true si en cours de traitement, false si arrêt
        this._nbReqs = 0;                       // Nombre de requêtes
        this._reqsLeft = 0;                     // Requetes restant à lancer
        this._reqsTreated = 0;                  // Requêtes traitées (retour ok ou false)
        this._reqsRunning = 0;                  // Requête en cours d'exécution
        this._maxRequest = 3;                   // Requetes simultanées max
     
        this.AddAfter = function(request)
        {
            //console.log("Add after");
            this._reqsQueue.push(request);
            this._reqsStatuts.push(false);
            this._reqsLeft++;
            this._nbReqs++;
     
            this.Start();
        };
     
        this.AddBefore = function(request)
        {
            //console.log("Add before");
            this._reqsQueue.unshift(request);
            this._reqsStatuts.unshift(false);
            this._reqsLeft++;
            this._nbReqs++;
     
            this.Start();
        };
     
        this.Start = function()
        {
            //console.log("-- ajout de requete, appel start -- "+this._traitementStatut);
            if(!this._traitementStatut)
            {
                this._traitementStatut = true;
                this.TreatQueue();    
            }
            else
            {
                //console.log("-- queue deja en execution --");
            }
        };
     
        this.TreatQueue = function()
        {
            console.log("### Lancement de la file d'attente ###");
            //setTimeout(this.RecursTreatQueue, this._overflowWaitTime);
            this.RecursTreatQueue();
            //console.log("---> Fin de traitement de la file");
            //this._traitementStatut = false;
        };
     
        this.RecursTreatQueue = function()
        {
            //console.log("---------");
            console.log("---------"+this._reqsTreated+"/"+this._nbReqs+" traitees, "+this._reqsRunning+" en execution, "+this._reqsLeft+" restantes");
     
            if(this._reqsLeft > 0)  // Reste des requêtes à lancer ?
            {
                console.log("Requete:");
                if(this._reqsRunning <= this._maxRequest)   // Emplacements de requêtes dispo
                {
                    // Recherche de l'ID à traiter
                    var idTreat = -1; 
                    for(i=0; i<this._nbReqs; i++)
                    {
                        if(!this._reqsStatuts[i])
                        {
                            idTreat = i;
                            break;
                        }
                    }
     
                    if(idTreat >= 0)
                    {
                        // Exécution de la requête
                        var iTemp = idTreat + 1;
     
                        console.log("    >> Lancement, id="+iTemp);
     
                        var requete = this._reqsQueue[idTreat];
                        this._reqsStatuts[idTreat] = true;
                        this._reqsLeft--;
                        this._reqsRunning++;
                        this._iterations = 0;
     
                        var that = this;
     
     
                        requete.success = [requete.success, function(){
                            that._reqsRunning--;
                            that._reqsTreated++;
                            console.log("    >> Réponse, id="+iTemp);
                            that.TreatQueue();
                        }];
     
                        jQuery.ajax(requete);
     
                        this.RecursTreatQueue();
                    }
                }
                else
                {
                    console.log(" ... surcharge, relancement a la reponse.");
                    this._traitementStatut = false;
                }
            }
            else
            {
                console.log("Fin de traitement");
                this._traitementStatut = false;
            }
        };
    }
    Puis dans mon code, je remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $.ajax({
            type : "GET",
            url : "monFichier.xml",
            data : "xyz",
            success: function(){...},
    ...});
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var ajaxQueue = new AjaxQueue();
     
    ajaxQueue.AddAfter({
            type : "GET",
            url : "monFichier.xml",
            data : "xyz",
            success: function(){...},
    ...});
    - Les requêtes sont placées dans un tableau.
    - Les requêtes peuvent êtres ajoutées en début ou fin de tableau. Un requête ajoutée en début de tableau sera la prochaine traitée.
    - Le traitement exécute les 4 premières requêtes du tableau, la 5ème est mise en attente.
    - Chaque réponse AJAX relance le traitement et exécute un maximum de 4 requêtes toujours en prenant le tableau dans le même sens.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête mysql lancée par ajax comportement bizarre
    Par reventlov dans le forum AJAX
    Réponses: 4
    Dernier message: 06/07/2015, 21h38
  2. Requête lancée en batch
    Par Jean-Philippe André dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 24/04/2008, 09h22
  3. Réponses: 1
    Dernier message: 27/03/2008, 18h42
  4. Réponses: 2
    Dernier message: 03/10/2007, 07h09
  5. Réponses: 8
    Dernier message: 14/01/2005, 09h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo