IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> jQuery Ajax afficher une très longue liste, ALgo difficile à pondre
Options
No6
posté 12 May 2015, 00:43
Message #1


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



J’ai, sur un serveur, plusieurs très longues listes d’objets (un inventaire à la Prévert) à afficher.

Pour des questions de réactivité , j’en passe par plusieurs requêtes Ajax :

L’idée c’est de commencer à afficher les 12 premiers éléments d’une des listes sur une page.

Puis ensuite de la compléter la liste sur la page en tache de fond.
Comme ca l’internaute n’a pas à attendre que les 12milliards de lignes soient transférées depuis le serveur pour commencer à contempler cette fichue liste.

Comme cette liste est trop longue pour entrer dans une seule réponse Ajax, je suis obligé de faire passer ces lignes 12 par douze, jusqu'à épuisement de la liste.

J’ignore aussi les tailles exactes de ces listes, celles-ci pouvant évoluer au gré de fantaisies insoupçonnables.
Donc, j’ignore combien de douzaines devront transiter, et je compte sur les retours de chaque douzaine pour indiquer si celle-ci est la dernière ou non.

Pour couronner le tout, l’internaute peut très bien vouloir décider de visualiser une autre liste, même si la liste en cours d’affichage n’est pas achevée de traiter.


J’ai un peu défriché l’algorithme à mettre en place.

Pour chaque liste j’utilise un ID différent, et je demande au serveur de me renvoyer systématiquement cet ID pour le comparer à l’ID courant.
Comme ca, si l’internaute change de liste, le traitement d’affichage d’une liste avec un ID différent est annulé.

La ou je coince, c’est que je me retrouve avec plusieurs requêtes Ajax à envoyer l’une après l’autre, et qui sont de part leur nature Asynchrone.
Je ne peux envoyer une requête que si la requête précédente est entièrement traitée, et accessoirement qu’elle indique bien que la liste n’es pas achevée…

Dans la panoplie des fonctions jQuery j’ai zieuté des trucs autour des fonctions deferred, mais sincèrement, j’ai du mal à y voir clair.

J’ai aussi l’impression que je vais avoir à mettre en place du récursif, alors que j’aurai préféré une boucle…
Mais quelque soit la soluce que vous pouvez me donner, je prends ; mes neurones font des nœuds avec cette histoire.


Ce message a été modifié par No6 - 12 May 2015, 00:50.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
Jaypee
posté 12 May 2015, 06:14
Message #2


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Salut No6,

Je n'ai rien de concret à te proposer mais seulement du "carburant pour la pensée". Il existe une initiative faisant partie du manifeste réactif intitulé "reactive streams", il y a des bases et des principes, mais peu de code concret, bien que l'api cliente en Js fasse aussi partie du design.

Les présentations peuvent t'inspirer de nouvelles directions de recherche.

Bonjour chez toi,
J-P

Ce message a été modifié par Jaypee - 12 May 2015, 06:15.
Go to the top of the page
 
+Quote Post
yponomeute
posté 12 May 2015, 06:50
Message #3


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 4 969
Inscrit : 26 Jan 2011
Lieu : Pollachius virens
Membre no 164 083



Salut,

Tu peux aussi t'inspirer du "lazy loading" utilisé pour les images, et ne récupérer les éléments que si l'utilisateur fait défiler la page https://github.com/tuupola/jquery_lazyload

Edit : je ne sais pas ce qu'il y a dans ta liste, mais 12 éléments ça me semble très faible pour être trop volumineux pour ajax. Tu récupères tes éléments en JSON ?

Ce message a été modifié par yponomeute - 12 May 2015, 06:55.


--------------------
MBP 2017 15" avec clavier pourri et touchbar inutile
Go to the top of the page
 
+Quote Post
Jaypee
posté 12 May 2015, 08:59
Message #4


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Nous sommes tous sur la même ligne, mais il est difficile de traiter ce problème "à l'unilatérale", il faut une archi client (JS) et serveur (Java EE ou .Net)

Et il est question d'un système d'événements, pour que le serveur réagisse aux clients, et les clients au serveur.
Les streams (flux) ne sont pas des collections (liste, ensemble...) mais davantage des itérateurs.

La différence est la "paresse", les actions réelles sont remises à plus tard, là où on va effectivement utiliser la donnée extraite du stream.
On peut imaginer un grand tableau et un stream permettant de le parcourir et un algo de tri. Le retour de la fonction de tri est immédiate. Seule la logique est analysée et transformée en code. C'est seulement au moment où on veut afficher les data que le code est mis en branle pour fournir le résultat effectif.

Ces slides dressent le décor : http://www.slideshare.net/rolandkuhn/reactive-streams

Celà reste ambitieux, et à la pointe des technos actuelles.
J-P
Go to the top of the page
 
+Quote Post
No6
posté 12 May 2015, 11:21
Message #5


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Merci,

Je commence juste à regarder vos réponses.

C'est du classique Serveur PHP et les messages sont en JSON.

c'est coté Client (Js / jQuery ) que je coince, sur la partie requête Ajax, promise, deferred, etc..

Et sinon 12 éléments c'est juste pour l'exemple, je regarderai par la suite jusqu'où je peux monter, tout en gardant une certaine fluidité

Je vous tiens informé de mes évolutions..

wink.gif

Ce message a été modifié par No6 - 12 May 2015, 11:22.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
yponomeute
posté 12 May 2015, 15:37
Message #6


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 4 969
Inscrit : 26 Jan 2011
Lieu : Pollachius virens
Membre no 164 083



Un article qui peut t’intéresser : http://josh.zeigler.us/technology/web-deve...o-big-for-json/


--------------------
MBP 2017 15" avec clavier pourri et touchbar inutile
Go to the top of the page
 
+Quote Post
Jaypee
posté 12 May 2015, 15:39
Message #7


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Tu trouveras sans doute une piste sérieuse avec Rx.js (il existe aussi un Rx.php)

https://github.com/Reactive-Extensions/RxJS

J-P
Go to the top of the page
 
+Quote Post
macpacher
posté 12 May 2015, 20:38
Message #8


Adepte de Macbidouille
*

Groupe : Membres
Messages : 143
Inscrit : 4 Dec 2013
Membre no 188 132



On est effectivement dans un problème de stream et de priorités temps réel. Ne maitrisant pas suffisamment les dessous d'Ajax, ni comment le navigateur gère le multi-tâche , je me concentrerai sur le besoin "métier"; on peut essayer d'analyser le comportement et l'attente de l'utilisateur et essayer d'anticiper les actions les plus probables : consulter la page suivante de la même liste, consulter une autre liste liée à la liste courante, revenir en arrière. Quel volume de données et temps de consultation sans besoin de recharger ?
Une piste :
  • identifier les actions utilisateur, plutôt que seulement les listes, avec un numéro d'ordre croissant, le numéro le plus élevé étant le plus récent et prioritaire
  • anticiper la consultation par des requêtes de préchargement associée à l'identifiant de l'action utilisateur courante
  • n'enchaîner une requête de préchargement que si la requête précédente de préchargement est entièrement traitée
  • abandonner le traitement d'une requête de préchargement si elle n'est plus associée à l'identifiant de la requête utilisateur courante
  • côté serveur, limiter la taille des réponses pour que le délai de réponse à une requête reste compatible (donc bien inférieur) au délai entre deux actions de l'utilisateur. Entre un cockpit d'avion de chasse, une vue googlemaps , une galerie photo ou une recherche duckduckgo, les délais ne sont pas les mêmes.



--------------------
Macmini6,2 - Mavrik
Go to the top of the page
 
+Quote Post
No6
posté 13 May 2015, 00:25
Message #9


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Bon, ben voila ou j'en suis, evidement je coince toujours au même endroit...

Le code HTML :
CODE
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Test lecture de Listes</title>
<link rel="stylesheet" href="assets/css/testLists.css" />
</head>
<body>
<header>
<h3>Liste Barbie</h3>
<span>...</span>
<button value="Barbie" disabled="disabled">Liste Barbie</button>
<button value="Ken">Liste Ken</button>
<button value="Godzilla">Liste Godzilla</button>
</header>
<section>
<!-- ici la liste-->
</section>

<script src="assets/js/jquery-2.1.4.min.js"></script>
<script src="assets/js/testLists.js"></script>

</body>
</html>


La partie css "assets/css/testLists.css"
Code
@charset "UTF-8";

body { font-family: sans-serif; width: 740px; margin: 20px auto; background-color: #23232e; font-size: 16px; }

header { width: 100%; overflow: auto; margin: 10px 0; }
header h3 { width: 300px; float: left; padding: 20px 0 0 0; color: wheat;}
header span { width: 320px; float: left; margin: 50px 0 0 0;  height: 40px; color:aquamarine; font-size: .8em; }
header button { width: 120px; height: 30px; font-weight: bold; }

section { width: 100%; height: 500px; overflow: auto; }
article { width: 90%; margin: 5px; padding: 5px; background-color:cornflowerblue; color:black; display: none;}



Tout de suite la partie PHP 'assets/php/RespLists.php'
CODE
<?php
mb_internal_encoding("UTF-8");

// listes à afficher : "nom de la liste" => nombre d'éléments constituants.
// juste pour exemple, en substitut d'appel de données depuis un SGBD...

$Listes["Barbie"] = 45;
$Listes["Ken"] = 26;
$Listes["Godzilla"] = 458;

$Ref_UI = (isSet($_POST['Ref_UI'])) ? $_POST['Ref_UI'] : 0; // Valeur référence (à retourner)
$NomListe = (isSet($_POST['NomListe'])) ? $_POST['NomListe'] : 'Barbie'; // nom de la liste
$NoElemRef = (isSet($_POST['NoElemRef'])) ? $_POST['NoElemRef'] : 0; // No du dernier élément affiché
$maxElems = (isSet($_POST['maxElems'])) ? $_POST['maxElems'] : 12; // nombre d'élements à renvoyer

$ListStatus = 'en cours...'; // vs 'finish' quand toute la liste est lue.


$MaxList = $Listes[$NomListe];

$noItem = $NoElemRef;
$T_Lignes = array();

for($i = 0; $i < $maxElems ; $i++) {
$noItem++;
if ($noItem > $MaxList ) {
$ListStatus = 'finish';
break;
}
else {
$T_Lignes[] = $NomListe.' élément n° '.$noItem;
$NoElemRef = $noItem;
}
}

$T_Repons["Ref_UI"] = $Ref_UI;
$T_Repons["ListStatus"] = $ListStatus;
$T_Repons["NoElemRef"] = $NoElemRef;
$T_Repons["ListElems"] = $T_Lignes;

header('Content-type: application/json');
echo json_encode($T_Repons);
exit(0);
?>


Et la partie JavaScript "assets/js/testLists.js"
CODE
$(document).ready(function () {

var gUI_Ref = 0,
gWaveRef = 0,
gWaveNb = 10,
gListDone = true;
$ListBox = $('section');


$('button').on('click', function() {


$('header h3').text( $(this).text() );
$('header span').text( 'En cours...' );
$('button').removeAttr('disabled');
$(this).attr('disabled','disabled');

BIBI( $(this).val() );

});
alert('étape1');

// BIBI('Barbie');

function BIBI(NomDeList) {
gUI_Ref++;
gListAgain = true;
inUI_Ref = gUI_Ref;
gWaveRef = 0;

$ListBox.empty();

alert('étape2');
do {
$.when(LoadList (NomDeList, inUI_Ref, gWaveRef )).done( function() {
alert('étapeN++');
});
} while ((gListAgain) && (inUI_Ref == gUI_Ref));
}

function LoadList (zListName, zUI_Ref, elm_Ref ) {
return $.Deferred(function(dfd) {

Call_Args = {
Ref_UI : zUI_Ref, // Valeur référence? pour chainer les listes.
NomListe : zListName, // nom de la liste
NoElemRef : elm_Ref, // No du dernier élément affiché
maxElems : gWaveNb // nombre d'élements à renvoyer
};

$.ajax({
url : 'assets/php/RespLists.php',
type : 'POST',
data : Call_Args,
cache : false,
dataType : 'json',
error : function(request, error) { alert("Erreur : responseText: "+request.responseText); },
success : function(data) {

if (data['Ref_UI'] == gUI_Ref)
{
gWaveRef = data['NoElemRef'];
gListAgain = (data['ListStatus'] != 'finish');
for(var i = 0; i < data['ListElems'].length; i++) {
$el = $('<article>').text(data['ListElems'][i]);
$el.appendTo($ListBox).delay(100*i).fadeIn(500, dfd.resolve);
}
}
else
dfd.resolve;
}
});
}).promise();
}
/********************************************************************************
**********************
// pour tester directement...

Call_Args = {
Ref_UI : gUI_Ref, // Valeur référence? pour chainer les listes.
NomListe : 'Barbie', // nom de la liste
NoElemRef : 0, // No du dernier élément affiché
maxElems : gWaveNb // nombre d'élements à renvoyer
};

$.ajax({
url : 'assets/php/RespLists.php',
type : 'POST',
data : Call_Args,
cache : false,
dataType : 'json',
error : function(request, error) { alert("Erreur : responseText: "+request.responseText); },
success : function(data) {

for(var i = 0; i < data['ListElems'].length; i++) {
$el = $('<article>').text(data['ListElems'][i]);
$el.appendTo($ListBox).delay(100*i).fadeIn(500);
}

}

});
********************************************************************************
*****************************/

}); // --> $(document).ready(


bien sur, il part dans les choux, je peux même pas ouvrir un débugger !

Je fais vraiment un blocage mental sur ces notions assynchrones, je comprends pas pour quoi, j'en comprends les grands principes, mais je vois pas comment utiliser leurs fonctions!
Ce soir relaxation, et demain grand bol d'air!

Ce message a été modifié par No6 - 13 May 2015, 01:14.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
No6
posté 13 May 2015, 00:59
Message #10


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



En tous cas vraiment merci a tous de vous interresser à mon histoire, ça réchauffe le coeur.

@ Jaypee
RxJS pourrait certainement être utile, mais ça fait un peu peur, ça fait un gros morceau à digérer...

@ yponomeute
effectivement, et je ne pensais pas qu'on pouvait atteindre (dans certains cas) le GigaOctet d'info dans une requête Ajax...
Mais ce qui est le plus intéressant et significatif (à mon avis) c'est de voir la dégradation des temps de réponses..!

@ macpacher
évidement, ce serai plus simple si je pouvais en passer par une pagination (ou attaquer ce probleme sous un autre angle), mais sur ce cas présent, les listes ont pour vocation d'être affichées dans leur intégralité.

même si au bout du compte cela risque de faire un truc indigeste à lire.
D'ailleurs, c'est un peu le but, car cette réalisation permettra par la suite de réorganiser l'info, par touches successives, jusqu'a avoir des "listes cohérentes"

Sinon ces listes sont au moins affichées en ordre alphabétique, et sont remplies de Tags et d'ensembles de listes (qui peuvent permettre à leur tour de consulter une nouvelle liste basée sur les tags choisis)

D'une certaine manière il n'y a qu'une seule liste, la première est basé sur l'ensemble principal, puis ensuite on navigue à l'intérieur, un peu comme dans un système de fichiers, mais avec des tags hiérachisés en plus.

Il y a aussi d'autres trucs, mais c'est déjà compliqué à expliquer, alors j'ai pris l'exemple des listes pour rester plus simple....

___ ____ ___
Sinon, j'ai trouvé ça sur la toile, mais je vois pas trop comment je pourrai m'en servir ?

https://css-tricks.com/multiple-simultaneou...allback-jquery/


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
Jaypee
posté 13 May 2015, 08:45
Message #11


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Note annexe: Les exemples de codes PHP montrent une vulnérailité à une attaque par injection de code JS.

Dans le champ NomListe, si tu entres : Barbie';alert('Coucou !');//
Il y a des chances que l'alerte (ou n'importe quel code JS mal-intentionné), s'éxécute.

J-P
Go to the top of the page
 
+Quote Post
No6
posté 13 May 2015, 11:44
Message #12


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Citation (Jaypee @ 13 May 2015, 09:45) *
Note annexe: Les exemples de codes PHP montrent une vulnérailité à une attaque par injection de code JS.

Dans le champ NomListe, si tu entres : Barbie';alert('Coucou !');//
Il y a des chances que l'alerte (ou n'importe quel code JS mal-intentionné), s'éxécute.

J-P


Bien vu, je fais pas assez attention à ce genre de truc, mais celui-la, je m'en rappellerai. wink.gif

mais, dans le cas présent le code PHP, n'est la qu'en exemple; pour le vrai, avec l'accès sur le SGBD, ce sera un peu plus "blindé".

Sinon, je m'oriente vers ue solution récursive, la requête Ajax ne fait pas 10.000 trucs, alors c'est pas vraiment la mer à boire...


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
No6
posté 13 May 2015, 12:36
Message #13


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Bon, ben finalement, le récursif fonctionne très bien, alors je fais avec.

mais j'aurai bien aimé comprendre le système " deferred " de jQuery.... un jour??

Pour ceux que cela intéresse voici le code retenu, seule la partie JS à changé :
CODE
$(document).ready(function () {

var gUI_Ref = 0,
gWaveNb = 10, // nombre d'élements à renvoyer à la suite par req Ajax..
$ListBox = $('section');


$('button').on('click', function() {


$('header h3').text( $(this).text() );
$('header span').text( 'En cours...' );
$('button').removeAttr('disabled');
$(this).attr('disabled','disabled');

AfficherListe( $(this).val() );

});

AfficherListe('Barbie'); // faut bien commencer avec une premiere liste, alors honnnneur aux filles...

function AfficherListe (NomListe) {
gUI_Ref++;
var zUI_Ref = gUI_Ref;
RunListe (NomListe, gUI_Ref, 0, gWaveNb);
}

function RunListe(xNomListe, xUI_Ref, lastElemNo, maxElemNb) {

Call_Args = {
Ref_UI : xUI_Ref, // Valeur référence? pour chainer les listes.
NomListe : xNomListe, // nom de la liste
NoElemRef : lastElemNo, // No du dernier élément affiché
maxElems : maxElemNb // nombre d'élements à renvoyer
};

$.ajax({
url : 'assets/php/RespLists.php',
type : 'POST',
data : Call_Args,
cache : false,
dataType : 'json',
error : function(request, error) { alert("Erreur : responseText: "+request.responseText); },
success : function(data) {

if (xUI_Ref == gUI_Ref) {

if (lastElemNo == 0) $ListBox.empty();

for(var i = 0; i < data['ListElems'].length; i++) {
$el = $('<article>').text(data['ListElems'][i]);
$el.appendTo($ListBox).delay(100*i).fadeIn(500);
}

if (data['ListStatus'] != 'finish')
RunListe (xNomListe, xUI_Ref, data['NoElemRef'], maxElemNb); // récursif, que les Dieux de Cobol nous protègent !
else
$('header span').text( 'Liste complétée !' );
}
}
});
}

}); // --> $(document).ready(



--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
Jaypee
posté 13 May 2015, 13:30
Message #14


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Une autre option qu'il ne faut pas négliger si les listes sont statiques: tout charger en mémoire dans une hash map géante.

Même si ça prend 1 ou 2 Go de mémoire, on peut plus facilement se le permettre de nos jours. Mais il faut aussi trouver un système de cache distribué pour permettre à chaque serveur d'être en phase pou rle contenu. Donc la bd n'est plus qu'un réservoir, lue une fois au démarrage d'un des serveur, puis le cache prend le relais et met à jour tous les noeuds.

J-P

Ce message a été modifié par Jaypee - 13 May 2015, 13:31.
Go to the top of the page
 
+Quote Post
No6
posté 13 May 2015, 14:00
Message #15


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Ouais..
Faudra que je réfléchisse à cette problématique de cache, ça pourrait s'avérer très payant !

L'autre partie du projet, c'est qu'il est amené à fonctionner en partage, et j'ai toute une gestion concurrente à développer aussi....

Mais je lâche pas l'affaire, je suis loin de me satisfaire d'un appel récursif dans mon code.
En attendant je vais au moins ajouter un compteur pour limiter la profondeur des appels, histoire de ne pas exploser la stack.
quitte à mettre u nbouton de reprise, voir aussi de pause....

En tout cas, c'est sur, faut que je potasse sérieusement l'aventures des requêtes asynchrone en jQuery.

Je corrigerai le code posté ici, avec les dernières corrections...

Ce message a été modifié par No6 - 13 May 2015, 14:02.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
No6
posté 13 May 2015, 18:00
Message #16


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



C'est encore moi,
c'est idiot, mais j'ai trouvé un meilleur moyen pour éviter de remplir la stack des appels récursifs...

J'ai juste remplacé l'appel :
Code
if (data['ListStatus'] != 'finish')
    RunListe (xNomListe, xUI_Ref, data['NoElemRef'], maxElemNb);
else.....
par :
Code
if (data['ListStatus'] != 'finish')
    window.setTimeout( RunListe, ....

Grosse ruse de Sioux... tongue.gif
du coup, je peux même envisager l'économie d'un appel Ajax, en vérifiant avant que je suis sur le même xUI_Ref...

code final...
CODE
$(document).ready(function () {

var gUI_Ref = 0, // globale servant de N° de référence sur la liste en cours
gWaveNb = 10, // nombre d'élements à renvoyer à la suite par req Ajax..
$ListBox = $('section');
$MsgBox = $('header span');

AfficherListe('Barbie'); // faut bien commencer avec une premiere liste, alors honnnneur aux filles...

$('button').on('click', function()
{
$MsgBox.text( 'En cours...' );
$('header h3').text( $(this).text() );
$('button').removeAttr('disabled');
$(this).attr('disabled','disabled');
AfficherListe( $(this).val() );
});

function AfficherListe (NomListe)
{
gUI_Ref++; // on change de liste, alors on change de référence
var zUI_Ref = gUI_Ref;
RunListe (NomListe, gUI_Ref, 0, gWaveNb);
}

function RunListe(xNomListe, xUI_Ref, lastElemNo, maxElemNb) {

Call_Args = {
NomListe : xNomListe, // nom de la liste
NoElemRef : lastElemNo, // No du dernier élément affiché
maxElems : maxElemNb // nombre d'élements à renvoyer
};

if (xUI_Ref == gUI_Ref) {
$.ajax({
url : 'assets/php/RespLists.php',
type : 'POST',
data : Call_Args,
cache : false,
dataType : 'json',
error : function(request, error) { alert("Erreur : responseText: "+request.responseText); },
success : function(data)
{
if (xUI_Ref == gUI_Ref)
{
if (lastElemNo == 0) $ListBox.empty();

for(var i = 0; i < data['ListElems'].length; i++)
{
$el = $('<article>').text(data['ListElems'][i]);
$el.appendTo($ListBox).delay(80*i).fadeIn(500);
}
if (data['ListStatus'] != 'finish')
window.setTimeout( RunListe, (80*i), xNomListe, xUI_Ref, data['NoElemRef'], maxElemNb ); // pour casser toute récursivité
else
$MsgBox.text( 'Liste complétée !' );
}
}
});
}
} // fait le job d'affichage de la liste...

}); // --> $(document).ready(


Ce message a été modifié par No6 - 20 May 2015, 01:10.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
Jaypee
posté 14 May 2015, 06:42
Message #17


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



La récursion était déjà "terminale", elle ne garde aucune opération en attente comme dans le cas de factorielle(n) = n * factorielle(n - 1) où la multiplication est en attente, et où plus n est grand, plus la pile se remplit.
Dans le cas de la factorielle, on la rend terminale en passant le résultat à une fonction auxiliaire récursive:

fact_aux(n, res) = fact_aux (n - 1, n * res) ici la récursion se fait à pile constante, quel que soit n.
et
factorielle (n) = fact_aux(n, 1)

Et l'étape suivante est de remplacer la récursion de fact_aux par une itération classique smile.gif
Mais la récursion reste souvent le plus court chemin vers une solution.

J-P

Go to the top of the page
 
+Quote Post
No6
posté 14 May 2015, 09:55
Message #18


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Oui, mais comme je ne sais pas trop comment les interpréteurs JS optimiseront mon code, et s'ils savent vraiment faire la différence entre une récursion terminale ou non...

sinon, un moyen simple, et dans ce cas la, s'aurait été de mettre un goto...

Mais il me semble que l'utilisation des labels n'est pas toujours implémenté.... ???

https://developer.mozilla.org/en-US/docs/We...tatements/label




Ce message a été modifié par No6 - 14 May 2015, 10:05.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 26th April 2024 - 11:31