Timer : settimeout & setinterval améliorés

Soyez le premier à donner votre avis sur cette source.

Vue 5 801 fois - Téléchargée 328 fois

Description

Et bien, une petite source après quelques 4 mois d'absence. J'arrive ici avec une source de calibre expert, assez lourde, qui permet de rajouter quelques fonctionnalités très intéressantes aux fonctions setTimeout et setInterval. De quoi s'agit-il ?

Il n'est pas inconnu que ces fonctions, couplées à clearTimeout et clearInterval proposent des fonctions de bases, parfois trop, ce qui posent problème. Un petit exemple très connu est la difficulté de définir des arguments pour la fonction anonyme précisé et la valeur du "this".

Et bien, je règle ces problèmes, et bien d'autres encore ! Voici lesquels :

#1 : Définir les arguments de la fonction anonyme : Cela est désormais possible. Ainsi, les arguments définis dans les fonctions (à partir du trosième) seront envoyés à la fonction anonyme. Schéma :

timer.createTimeout(fonction(a,b,c){...},1000,this,a,b,c);

#2 : La valeur du "this" : Le keyword "this" peut être défini en troisième argument, comme démontré dans le schéma ci-haut

#3 : Programmation en POO qui permet d'accéder à certaines fonctions/propriétés, comme exécuter d'avance (.exec() ) ou annuler facilement (.clear() ) sans avoir besoin de connaître l'ID du timer.

#4 : Détruire TOUS les setTimeout/setInterval définis : J'ai ajouté la fonction timer.clearAll()

Et cela en modifiant presque pas la fonction originale ! Toutefois, les fonctions timer.createTimeout/timer.createInterval ont un comportement semblable à leurs équivalents :
- Défini un temps d'exécution en millisecondes
- Possibilité d'exécuter du texte ou une fonction anonyme

Le code est très difficile, je n'ai pas encore ajouté de commentaires, je le ferai prochainement. S'il y a problèmes avec certaines parties, merci de me faire signe.

Pour voir le code en action, ainsi qu'une documentation mêlée à une explication, téléchargez le ZIP !

TIMER.JS Version 1.2

SOURCE ORIGINALE (qui ne lui ressemble plus) : Inspiré de http://arguments.callee.info/2008/11/10/passing-arguments-to-settimeout-and-setinterval/ (sans espaces, s'il y a espaces)

NOTES PAR RAPPORT À LA VERSION 1.1.2 : Merci de revoir la documentation, puisque la structure en POO est complètement différente. Il n'est plus possible de connaître le nombre de Timers définis.

Source / Exemple :


/*------------------

| TIMER API |

JDMCREATOR, 2011 VERSION 1.2 CODE START HERE http://www.javascriptfr.com/code.aspx?ID=53911 ------------------*/(function (f) { // f = fonctions qui remplaceront les setTimeout/setInterval // Définition du timer window.timer = { // key = clés des différents Timers key: {}, // Version version: '1.2', // Build : Version en nombre. build: 120, // length = nombre de timers length: 0, // _fn = Fonction temporaire permettant la construction de Timer __fn: function (f, wt) { // f = Fonction setTimeout/setInterval // wt = Nombre. 1 = Timeout, 2 = Interval return function (fn, time, cntx) { // Fonction pour créer un Timer. Fn = fonction à exécuter. time = Temps avant l'exécution. cntx = contexte; cntx = cntx || window; // Définit le contexte (cntx); var a = [].slice.call(arguments, 3); // a = Array d'arguments à passer // Si fn est une String, on l'envoie à la fonction Timer, if (fn.toString() === fn) { var t = f(function () { eval.call(cntx, fn); }, time); // Sinon, on exécutera la fonction directement, à l'aide de 'apply' } else { var t = f(function () { fn.apply(cntx, a); }, time); } // Retourne un objet. return this.convert([fn, a, wt, time], t, cntx); } }, // On supprime tous les Timers clearAll: function () { var k = this.key; for (var i in k) { var l = k[i]; if (!isNaN(i)) { if (l[2] == 1) { clearTimeout(i); } else { clearInterval(i); } } } }, // Créer un objet à partir d'un ID convert: function (k, id, cn) { // Si k est un ID, on crée if (!isNaN(parseInt(k))) { id = k; var k = this.key[k]; if (!k) { return false } } // Création de l'objet return { // type. Nombre. 1 = timeout, 2 = interval type: k[2], // source (fonction/texte à exécuter) source: k[0], // Temps time: k[3], // Contexte (si créé à partir des fonctions bruts, ce sera window) context: cn || window, // Liste des arguments args: k[1], // ID id: id, // Exécute d'avance le timer. Si argument à 'true', on ne supprimera pas le timer exec: function (keep) { var c = this.context; var s = this.source; if (s.toString() !== s) { s.apply(c, this.args); } else { eval.call(c, s); } if (!keep) { this.clear(); } }, // Supprimer le timer clear: function () { wt = this.type; if (wt == 1) { clearTimeout(id); } else if (wt == 2) { clearInterval(id); } } }; } }; // Création des fonctions createTimeout et createInterval timer.createTimeout = timer.__fn(setTimeout,1); timer.createInterval = timer.__fn(setInterval,2); // Supprime la fonction temporaire __fn); delete timer.__fn; // On remplace les fonctions bruts. window.setTimeout = f(window.setTimeout, 1); window.setInterval = f(window.setInterval, 2) })(function (f, wt) { // a = arguments var a = [].slice.call(arguments, 2); return function (c, t) { // On crée la fonction à envoyer à la fonction brute. var j = f(c, t); window.timer.length++; window.timer.key[j] = [c, a, wt, t]; return j; } });

Conclusion :


DOCUMENTATION :

Merci de voir le fichier 'demo.html' ! La version commenté du script n'est disponible qu'ici. Elle n'est fournie dans le ZIP.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

jdmcreator
Messages postés
647
Date d'inscription
samedi 30 décembre 2000
Statut
Membre
Dernière intervention
20 juillet 2012
5
Voilà pour la version commentée !
jdmcreator
Messages postés
647
Date d'inscription
samedi 30 décembre 2000
Statut
Membre
Dernière intervention
20 juillet 2012
5
Bonjour Kimjoa, je te répond rapidement de mon téléphone :

Pour ton idée de créer une classe groupé, je pourrais ajouter la possibilité de définir un 'name' au timex et de supprimer tous les timex ayant ce nom. Ce serait la méthode la plus simple.

Pour eval, je ne comprends pas pourquoi on ne pourrait pas choisir un autre contexte :S Est-ce parce que cela n'a aucun résultat ?

Quant à la partie que tu ne comprends pas, si tu regardes à la fin de mon fichier demo.html, j'explique qu'il est possible de convertir un Timex créé grâce aux méthodes classiques setTimeout/setInterval en passant l'ID du timex à la fonction timer.convert(ID) . Cette fonction a donc 2 utilités : une que le codeur ne verra jamais (celle avec les Array, qui me permet de réduire mon code) et celle décrite dans la documentation.

Et merci pour la dernière remarque :) C'est impressionnant tout ce que Javascript nous permet. Et c'est pour cette raison que je vais commenter la source le plus tôt possible !

JDMCreator
cs_Kimjoa
Messages postés
264
Date d'inscription
vendredi 6 mai 2005
Statut
Membre
Dernière intervention
19 septembre 2014

Salut jdmcreator!

Ton code me plais déjà mieux ;).
L'idée de renvoyer un objet lors de la création d'un timex est plutot bien vue.

En faite quand je t'ai dit de préférer une approche POO, je pensais plus à quelque chose du genre :

var monGroupeDeTimer = new Timers();
var monTimer = monGroupeDeTimer.createTimeout(...);
var monInterval = monGroupeDeTimer.createInterval(...);
...
monGroupeDeTimer.clearAll();

Avec aussi, une méthode de classe clearAll qui fait la même chose mais pour tout les timer , et non un groupe instancié.
Mais bon c'est un peux chipotter, d'autant plus qu'il aurait été nécessaire de répéter certaines autre méthodes d'instance, pour permettre de ne pas être obliger l'instanciation d'un groupe.

Je comprends presque tout ton code sauf une partie :
if (!isNaN(parseInt(k))) {id k;var k this.key[k];if (!k) {return false}}

k est sencé etre un tableau .... pourquoi le transformer en nombre et tester isNaN ?

Sinon, du coté du eval.
f(function () {eval.call(cntx, fn);}, time);
Ca me semble une érreur.
eval doit toujours être appellé au niveau global. Le contexte de toute facon sera évalué en même temps.
donc eval.call(window, fn)

J'ai pas d'autre remarque sinon. Enfin si peux être :).
C'est un code compliqué quand même , dans le sens ou c'est une succession de lambda comme on dit ...
Des fonctions passé en arguments qui retourne des fonctions etc... Il est pas à la porté du premier javascripteur !
C'est un beau tour de force de ce que permet javascript , son coté dynamique et fonctionnelle

Tchuss!
jdmcreator
Messages postés
647
Date d'inscription
samedi 30 décembre 2000
Statut
Membre
Dernière intervention
20 juillet 2012
5
Bonjour Kimjoa,

J'ai posté la version 1.2 . Je n'ai pas encore commenté, mais si tu pourrais regarder tout cela (le fichier demo.html explique assez bien) et me donner tes commentaires, ce serait gentil =) Malheureusement, j'ai encore modifié les fonctions setTimeout/setInterval, mais dans une moins grande ampleur que dans les versions précédentes. J'essaierai de réduire encore plus les impacts dans les prochaines mises à jour. Le code contient encore des bugs que je m'efforce à régler, mais comme je ne serai pas là en fin de semaine, la version 1.2.1 et la version commenté devra encore attendre !

Merci,

JDMCreator
jdmcreator
Messages postés
647
Date d'inscription
samedi 30 décembre 2000
Statut
Membre
Dernière intervention
20 juillet 2012
5
@Kimjoa :

Le problème, c'est que si ne redéfinis pas les méthodes Timex, je ne peux pas lister les Timers définis (pour pouvoir les supprimer via clearAll() )

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.