Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

implémenter une function "execAfter"

7 réponses
Avatar
unbewusst.sein
sur certaines pages, j'efface le contenu d'un <pre />, ligne après ligne
(comptage des "\n") avec une temporisation (feedback utilisateur sinon
ça va trop vite est on a l'impression que rien n'a changé)

et j'aimerais lancer qqc quand c'est fini.

j'ai essayé avec window.setTimeout, sans succès, firefox me donne une
erreur de syntaxe, c'est aprox. :

function execAfter(condition,action,param,count){
if(condition||count>20){
action(param);
} else {
count++;

window.setTimeout("execAfter("+condition+","+action+","+param+","+count+
")",100);
}
}

firefox me dit que la syntaxe est incorrecte, ça vient sans doute de
l'argument 'action' qui est une fonction ?

donc, question : est-il possible de passer en paramètre une function
dans un setTimeout ?

je tiens à passer cette function par variable car ça me permettrait
d'avoir une function "execAfter" générique...

euh, bien sûr "condition" varie au cours du temps, je veux dire
généralement quand je lance "execAfter" condition est à false et passe
ensuite à true...

pour être + précis, je voudrais généraliser, paramétriser, cette
fonction, qui, elle 'marche' :

function wipe(){
// décomposition du contenu de <pre /> en lignes :
var lines=log.innerHTML.split("\n");//alert(lines.length);
// si plus d'une ligne, on continue à effacer :
if(lines.length>1){
wipe_ended=false;
lines.pop(); // on vire la dernière ligne
log.innerHTML=''; // effacement de tout le <pre />
// ré-écriture du <pre /> dernière ligne en moins :
log.appendChild(document.createTextNode(lines.join("\n")));
// temporisation pour feedback utilisateur :
window.setTimeout("wipe()",100);
} else {
// plus rien à effacer dans le <pre />
wipe_ended=true;
// on peut donc réécrire qqc de nouveau (ou identique) dans le <pre
/>
log.appendChild(document.createTextNode(reportText));
}
}

--
Une Bévue

7 réponses

Avatar
SAM
pour être + précis, je voudrais généraliser, paramétriser, cette
fonction, qui, elle 'marche' :

function wipe(){
// décomposition du contenu de <pre /> en lignes :
var lines=log.innerHTML.split("n");//alert(lines.length);
// si plus d'une ligne, on continue à effacer :


alors pourquoi ne pas simplement étoffer un peu ce wipe() ?

function wipe(quoi, reportText) {
var log = document.getElementById(quoi);
var lines = log.innerHTML.split(/[rn]/);
log.innerHTML = '';
var L = lines.length-1;
if(L==0) {
log.appendChild(document.createTextNode(reportText));
return;
}
for(var i=0; L>i; i++) {
log.innerHTML += lines[i];
if(i<L-1) log.innerHTML += 'n';
}
setTimeout(function(){wipe(quoi,reportText);},200);
}

function execAfter(condition,action,param,count){
if(condition||count>20){
action(param);
}
else {
count++;
setTimeout( function() {
execAfter(condition,action,param,count);
}, 100);
}
}


<p><a href="javascript:wipe('ici','texte 1ntexte 2');">wipe</a>
<pre id="ici">
function wipe(quoi, reportText) {
var log = document.getElementById(quoi);
var lines = log.innerHTML.split(/[rn]/);
log.innerHTML = '';
var L = lines.length-1;
if(L==0) {
log.appendChild(document.createTextNode(reportText));
return;
}
for(var i=0; L>i; i++) {
log.innerHTML += lines[i];
if((L-1)>i) log.innerHTML += 'n';
}
setTimeout(function(){wipe(quoi,reportText);},200);
}

</pre>

Avatar
unbewusst.sein
SAM wrote:


alors pourquoi ne pas simplement étoffer un peu ce wipe() ?


euh, je regarderai ton idée demain matin, là, l'effet de mon verre de
chimay est tel que...

;-)

mais pourquoi mets-tu split(/[rn]/) tu penses que le navigateur peut
ajouter un r quand je n'ai mis que des n ???

mais bon ton wipe est une fonction spécifique alors que ce que je
cherchais à faire, plus généralement, est une fonction qui lance une
action sous condition de la fin d'une autre, sans bien sûr monopoliser
le cpu pendant le temps d'attente. (**)

cependant, l'avantage de ta version est que 'log' comme 'reportText' ne
sont plus en global...


question : "".split(/[rn]/) ça a quelle longueur ? 1 ?
càd [""] ???

** j'ai pensé à généraliser car j'ai un autre cas où je dois attendre le
onload de n images pour déclencher une action.

ou encore, en XHR, déclencher la transformation du fichier xml par le
fichier xsl quand les deux ont été téléchargés...

je sais qu'il y a des gens qui essaient d'implémenter le multi-threading
en js...

à part ça, je viens de découvrir que WebKit (et WebKit/Gtk) passent
l'acid3 test à 100 %...
--
Une Bévue

Avatar
SAM
SAM wrote:

alors pourquoi ne pas simplement étoffer un peu ce wipe() ?


mais pourquoi mets-tu split(/[rn]/) tu penses que le navigateur peut
ajouter un r quand je n'ai mis que des n ???


Dans mon test (dont ébauche donnée) mon éditeur texte doit certainement
mettre des r pour les fins/retours de lignes dans le <pre>, puisque le
split('n') laisse alors Fx de marbre

mais bon ton wipe est une fonction spécifique alors que ce que je
cherchais à faire, plus généralement, est une fonction qui lance une
action sous condition de la fin d'une autre, sans bien sûr monopoliser
le cpu pendant le temps d'attente. (**)

cependant, l'avantage de ta version est que 'log' comme 'reportText' ne
sont plus en global...


et qu'on y attend la condition sans qu'elle soit spécifiée de
l'extérieur ...

question : "".split(/[rn]/) ça a quelle longueur ? 1 ?
càd [""] ???


Je ne comprends pas ce que tu demandes,
c'est une bête reg-expression basique :
(scinder là où on) trouve ou r ou n
ce qui permet de satisfaire à l'écriture par mon éditeur et à la
ré-écriture par la fonction

oui : "".split(/[rn]/).length = 1 c a d : une ligne (vide)?
et : "".split(/[rn]/)[0] = '' c a d : inchangé
et : "".split(/[rn]/)[1] = 'undefined' c a d : inexistant

Quel est le blème à ce niveau ?

** j'ai pensé à généraliser car j'ai un autre cas où je dois attendre le
onload de n images pour déclencher une action.


Normalement on attend le onload de la dernière image (tout simplement)
pour passer à autre chose.
if(i==n) autreFonction();

Il doit donc suffire de passer l'argument 'countMaxi'
(le truc true/false doit aussi être possible mais il lui faudra bien un
indice pour basculer ? 'countMaxi' par exemple ?)


ou encore, en XHR, déclencher la transformation du fichier xml par le
fichier xsl quand les deux ont été téléchargés...


if(req.responseXML.documentElement) ?

ou les trucs réponses serveur :

if (req.readyState==4) {
if (req.status= 0) {
if(req.responseXML) {
if(req.responseXML.documentElement) {
if(url1 && url2) loadXMLDoc('',url2);
else fonctionTraitement();
}
}
}
}

Je vois mal une fonction générique pour traiter à la fois le XHR (qui
attends le serveur) et le JS qui tourne en client pur.

je sais qu'il y a des gens qui essaient d'implémenter le multi-threading
en js...


Oui, bon ... c'est déjà pas si simple de faire un if, alors ...

à part ça, je viens de découvrir que WebKit (et WebKit/Gtk) passent
l'acid3 test à 100 %...


Bien fait pour eux ! ça leur apprendra à faire les marioles.

--
sm


Avatar
Olivier Miakinen
Le 27/04/2008 00:13, SAM répondait à Labévue :

mais pourquoi mets-tu split(/[rn]/) tu penses que le navigateur peut
ajouter un r quand je n'ai mis que des n ???


Dans mon test (dont ébauche donnée) mon éditeur texte doit certainement
mettre des r pour les fins/retours de lignes dans le <pre>, puisque le
split('n') laisse alors Fx de marbre


Le délimiteur standard pour les communications internet est CRLF (r
plus n), et il ne serait pas surprenant que les outils standard tels
qu'un serveur web ou un interprête PHP transforment silencieusement un
simple LF (ou un simple CR sur Macintosh) en la séquence CRLF. Noter
que cela n'est pas indispensable car il me semble que les trois sont
tolérés en ce qui concerne les pages Web.


Avatar
unbewusst.sein
SAM wrote:

mais pourquoi mets-tu split(/[rn]/) tu penses que le navigateur peut
ajouter un r quand je n'ai mis que des n ???


Dans mon test (dont ébauche donnée) mon éditeur texte doit certainement
mettre des r pour les fins/retours de lignes dans le <pre>, puisque le
split('n') laisse alors Fx de marbre


ok, tu utilises quoi sur Mac OS X ? perso TextMate qui a un 'bundle'
JavaScript Lint qui vérifie la syntaxe.

mais bon ton wipe est une fonction spécifique alors que ce que je
cherchais à faire, plus généralement, est une fonction qui lance une
action sous condition de la fin d'une autre, sans bien sûr monopoliser
le cpu pendant le temps d'attente. (**)

cependant, l'avantage de ta version est que 'log' comme 'reportText' ne
sont plus en global...


et qu'on y attend la condition sans qu'elle soit spécifiée de
l'extérieur ...


oui, hier soir j'avais mal lu ta réponse...


question : "".split(/[rn]/) ça a quelle longueur ? 1 ?
càd [""] ???


Je ne comprends pas ce que tu demandes,

Quel est le blème à ce niveau ?


yenapa ;-)

** j'ai pensé à généraliser car j'ai un autre cas où je dois attendre le
onload de n images pour déclencher une action.


Normalement on attend le onload de la dernière image (tout simplement)
pour passer à autre chose.
if(i==n) autreFonction();


ben rien n'est moins sur que ce soit la dernière demandée qui arrive en
dernier (taille), perso, je ne compte pas là-dessus.

ou encore, en XHR, déclencher la transformation du fichier xml par le
fichier xsl quand les deux ont été téléchargés...


if(req.responseXML.documentElement) ?

ou les trucs réponses serveur :
<snip />


Je vois mal une fonction générique pour traiter à la fois le XHR (qui
attends le serveur) et le JS qui tourne en client pur.


une attente, c'est une attente.

--
Une Bévue


Avatar
SAM

une attente, c'est une attente.


et comme ça n'existe pas en JS ...

ne reste qu'à bien gérer la succession des fonctions ...
... comme le onload sur image qui lance le chargement de l'image
suivante de la liste
(et qui bloque tout dès qu'une image est manquante ou que le brouteur
refuse d'exécuter ce onload :-( )

** j'ai pensé à généraliser car j'ai un autre cas où je dois
attendre le onload de n images pour déclencher une action.
Normalement on attend le onload de la dernière image

pour passer à autre chose.
if(i==n) autreFonction();


ben rien n'est moins sur que ce soit la dernière demandée qui arrive
en dernier (taille), perso, je ne compte pas là-dessus.


Si tu ne charges pas tout en vrac mais successivement ... la dernière
est la dernière !

function loadImgs(listArray, autreFonction, params) {
var count = 0, max = listArray.length, I = [];
var loadImg = function() {
if(max>count) {
var I[count] = new Image();
I[count].onload = loadImg;
I[count].src = listArray[count];
count++;
}
else autreFonction(params);
}
loadImg();
}

exemple :
<http://cjoint.com/?eBnHZuHqvS>

--
sm



Avatar
unbewusst.sein
SAM wrote:

et comme ça n'existe pas en JS ...


on peut chercher à produire du code réutilisable.
ce qui me manquait, et que tu m'as donné, c'est l'astuce :

setTimeout( function() {
execAfter(condition,action,param,count);

qui consiste à wrapper la fonction à appeller dans une fonction
anonyme...

--
Une Bévue