Ce script a pour objectif d'exécuter un grand nombre de requêtes AJAX simultanées en gérant un ordre de priorité.
Classe
/** * AjaxQueue * Classe permettant de mettre les requêtes AJAX en file d'attente et d'en traiter un maximum de 4 simultanément */ var AjaxQueue = function() { this._reqsQueue = []; // Tableau des reqûetes dans la file d'attente this._reqsStatuts = []; // Tableau du statut des reqûetes, false si en attente, true si traité ou en cours this._traitementStatut = false; // true si en cours de traitement, false si arrêt this._nbReqs = 0; // Nombre de requêtes dans le tableau this._reqsLeft = 0; // Requetes restant à lancer, nombre de _reqsStatuts[] à false this._reqsTreated = 0; // Requêtes traitées (réussite OU echec), une partie des _reqsStatuts[] à true this._reqsRunning = 0; // Requête en cours d'exécution, l'autre partie des _reqsStatuts[] à true this._maxRequest = 4; // Requetes simultanées max this._debugg = false; // Affiche toutes les lignes de débugg si activé /** * Ajoute une requête AJAX en fin de file. Elle sera traitée après les autres. * @param {Ajax Obj} request: La requête Ajax au format jQuery */ this.AddAfter = function(request) { this.DebugLog("== Nouvelle requete AddAfter =="); this._reqsQueue.push(request); this._reqsStatuts.push(false); this._reqsLeft++; this._nbReqs++; this.Start(); }; /** * Ajoute une requête AJAX en début de file. Elle sera la prochaine traitée. * @param {Ajax Obj} request: La requête Ajax au format jQuery */ this.AddBefore = function(request) { this.DebugLog("== Nouvelle requete AddBefore =="); this._reqsQueue.unshift(request); this._reqsStatuts.unshift(false); this._reqsLeft++; this._nbReqs++; this.Start(); }; /** * Réinitialise la file d'attente, supprime les requêtes, remet les compteurs à 0. */ this.RazQueue = function() { this._traitementStatut = false; this._reqsQueue = []; this._reqsStatuts = []; this._reqsLeft = 0; this._reqsRunnuing = 0; }; /** * Démarre le traitement de la file d'attente si celui-ci n'est pas déjà en cours d'éxecution */ this.Start = function() { this.DebugLog("-- Nouvelle requete en attente -- Guichet ouvert: "+this._traitementStatut); if(!this._traitementStatut) { this.DebugLog("### Ouverture du premier guichet, traitement des requetes ###"); this._traitementStatut = true; this.RecursTreatQueue(); } else { this.DebugLog("-- Guichet deja ouvert --"); } }; /** * Traitement de la file d'attente lancé récursivement. */ this.RecursTreatQueue = function() { this.DebugLog("------------------------------------------------"); this.DebugLog("-- "+this._reqsTreated+"/"+this._nbReqs+" traitees, "+this._reqsRunning+" en execution, "+this._reqsLeft+" restantes --"); this.DebugLog("------------------------------------------------"); if(this._reqsLeft > 0) // Reste des requêtes à lancer ? { this.DebugLog("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; this.DebugLog(" >> Prise en charge de la requete num:"+iTemp); var requete = this._reqsQueue[idTreat]; this.DebugLog(" >> ",requete); this._reqsStatuts[idTreat] = true; this._reqsLeft--; this._reqsRunning++; var that = this; requete.success = [requete.success, function(){ that.DebugLog(" >> Réponse de Requête N°:"+iTemp+" > OK"); }]; requete.error = [requete.error, function(){ that.DebugLog(" >> Réponse de Requête N°"+iTemp+" > KO /!\ "); }]; requete.complete = [requete.complete, function(){ that.DebugLog(" >> Requête N°"+iTemp+" laisse sa place à la suivante"); that._reqsRunning--; that._reqsTreated++; that.RecursTreatQueue(); }]; jQuery.ajax(requete); this.RecursTreatQueue(); } } else { this.DebugLog(" ... guichets débordés, prends place dans la file."); this._traitementStatut = false; } } else { this.DebugLog("Fin de traitement"); this.DebugLog("### Fermeture des guichets ###"); this._traitementStatut = false; } }; /** * Active le mode débugg */ this.DebugStart = function() { this._debugg = true; return "Activé"; } /** * Stoppe le mode débugg */ this.DebugStop = function() { this._debugg = false; return "Désactivé"; } /** * Affiche le log du traitement si le débug est activé. */ this.DebugLog = function(message, obj) { if(!this._debugg){return false;} obj = (typeof(obj) == "undefined")?'':obj; console.debug(message,obj); } }