Dans la série gist de la semaine, j'ai décidé cette semaine de vous faire partager deux patterns que j'ai découvert alors que je regardais le screencast Paul Irish : 10 Things I Learned from the jQuery Source, permettant d'oublier setInterval et eval. Je vous conseille fortement d'y jeter un oeil si vous vous intéressez au JS et à jQuery en particulier. De plus, ses screencasts sont plutôt marrants, pleins d'easter egg et de subtilités(loopsiloopsiloo!). Et si vous ne le faîtes pas encore, je vous conseille également très fortement de suivre le podcast yayQuery (version Audio/Vidéo au choix!).

Asynchronous recursion

Récursion asyncrhone de par chez nous. Vous avez peut-être déja entendu parler de setInterval, et du fait qu'il est déprécié et souvent considéré comme une mauvaise pratique, pouvant apporter des comportements innatendus. Voilà pourquoi:

Ce code va basiquement appeller doStuff toutes les 100ms, sans aucune considération pour l'appel à doStuff qui peut prendre finalement plus de 100ms. On peut se retrouver avec des situations délicates, si ce n'est pas chaotiques. En tout cas, ce n'est certainement pas une situation dans laquelle on souhaite se retrouver.

On peut cependant faire beaucoup mieux (et ceci en regardant yayQuery):

Ce code fait a peu prés la même chose, à la différence près que setTimeout attend que doStuff ait bel est bien fini son boulot avant d'enregistrer un callback à exécuter dans 100ms. On garde donc ce délai de 100ms qu'on appliquait avec setInterval.

Un petit mot sur arguments.callee qui référence la fonction parent (la closure autour self-executed, clotûre auto executé de par chez nous... (function(){})();), le hic étant qu'arguments.callee est devenu déprécié dans ES5. Le seul moyen de contourner ceci est d'utiliser une fonction nommée (le nom est au choix!) au niveau de notre closure.

Yay! (Ou vous pouvez aussi utiliser la version de Paul Irish loopsiloopsiloo qui est un super nom de fonction!) Ce petit pattern de récusion est vraiment sympa et très élégant. Il s'applique aussi parfaitement bien au contexte XHR où l'on remplace l'utilisation de setTimeout par l'helper ajax de votre choix (et de votre librairie préférée):

Permettant par exemple d'implémenter un simple long-polling ou d'effectuer le chargement asyncrhone d'un arbre récursivement.

Propre, simple, efficace, puissant, que demander de plus? Ah si, suivez yayQuery.

Parlons eval...

Et d'une alternative plutôt sexy qu'on peut retrouver dans la méthode parseJSON introduit dans la version 1.4.1, que vous pouvez retrouver ici.

L'équivalent de:

Mais que se passe t-il? (Façon Les Inconnus)

SI l'on se risque à tenter dans notre console javascript le statement (new Function("return x = 10")), vous devriez voir:

Ce code ici n'est pas très propre et n'est que prétexte à expliquer ce qu'il se passe. Assigner 10 à la variable globale x est à éviter ;)

L'utilisation du constructor Function vous permet de créer une fonction anonyme (qui n'est pas nommé) à partir d'une string. Appliqué à un retour JSON, cela donnerait:

[object Object] alt="BadAss not evals" />

Wooow, je viens juste d'apprendre comment me passer d'eval... Bien que la meilleure façon reste de ne pas en avoir besoin ;)

Au fait, vous ai-je déjà dit de vous abonner au podcast yayQuery?