<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title><![CDATA[Forum du club des développeurs et IT Pro - Blogs - Le Blog d'un Ninja codeur par yahiko]]></title>
		<link>https://www.developpez.net/forums/blogs/676693-yahiko/</link>
		<description>Developpez.com, le Club des Développeurs et IT Pro</description>
		<language>fr</language>
		<lastBuildDate>Fri, 17 Apr 2026 18:11:05 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>15</ttl>
		<image>
			<url>https://forum.developpez.be/images/misc/rss.jpg</url>
			<title><![CDATA[Forum du club des développeurs et IT Pro - Blogs - Le Blog d'un Ninja codeur par yahiko]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/</link>
		</image>
		<item>
			<title><![CDATA[Les langages de programmation les plus populaires en 2017 selon l'IEEE]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b3395/langages-programmation-plus-populaires-2017-selon-l-ieee/</link>
			<pubDate>Wed, 19 Jul 2017 11:07:11 GMT</pubDate>
			<description><![CDATA[L'IEEE vient de publier son...]]></description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">L'IEEE vient de publier son classement annuel des langages les plus populaires en 2017.<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p295263d1500461768/autres-langages/perl/langage/langage-fonction-perl-ex-cuter-commandes-consoles/mjkynziznq.jpeg/" border="0" alt="Nom : MjkyNzIzNQ.jpeg
Affichages : 3088
Taille : 92,5 Ko"  style="float: CONFIG" /></div><br />
De façon assez surprenante, on peut y voir le langage <b>Python</b> prendre la première place, et des langages comme <b>R</b> être devant <b>JavaScript</b> ou <b>PHP</b>. Curieux.<br />
<br />
Il est à mettre au crédit de cette étude la mise à disposition de leur <u><a href="http://spectrum.ieee.org/ns/IEEE_TPL_2017/methods.html" target="_blank">méthodologie</a></u> ainsi que la possibilité de <u><a href="http://spectrum.ieee.org/static/interactive-the-top-programming-languages-2017" target="_blank">filtrer les domaines d'activité de façon interactive</a></u>.<br />
<br />
Cependant, même en ne choisissant par exemple que le domaine des applications Web, <b>Python</b> reste n°1 devant <b>Java</b>, <b>C#</b> puis <b>JavaScript</b> avec un écart tout à fait significatif quant à ce dernier : un indice de 100.0 pour Python contre 85.5 pour JavaScript. Chacun pourra se faire sa propre opinion de ce classement. Il doit sans doute il y avoir une part de vérité. La principale difficulté étant de savoir laquelle.<br />
<br />
<i>source : <u><a href="http://spectrum.ieee.org/computing/software/the-2017-top-programming-languages" target="_blank">The 2017 Top Programming Languages</a></u></i></blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b3395/langages-programmation-plus-populaires-2017-selon-l-ieee/</guid>
		</item>
		<item>
			<title>Comment surmonter le blocage du programmeur</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b3392/surmonter-blocage-programmeur/</link>
			<pubDate>Tue, 18 Jul 2017 13:35:11 GMT</pubDate>
			<description>Un article publié sur le site...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">Un article publié sur le site <u><a href="https://hackernoon.com/how-to-solve-programmers-block-18363c040656" target="_blank">HackerNoon</a></u> fait un parallèle intéressant entre l'activité d'écrire un roman et celle d'écrire un programme. Parallèle assez saugrenu avec la vision très segmentée de notre système scolaire, les littéraires d'un côté et les scientifiques de l'autre, mais en balayant les différents points mentionnés, il apparaît que pas mal d'entre eux sont tout à fait pertinents.<br />
<br />
La liste commence par 0, on parle d'informatique quand même 8-)<br />
<br />
<b><font size="3">0. La programmation d'abord</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Commencer votre journée par la programmation avant toute autre activité (sauf le café peut-être) car nous sommes les plus créatifs le matin.
			
		</div>
	</div>
</div>Je suis assez d'accord avec elle. La programmation est un exercice cérébral qui demande beaucoup de ressources et même si le mythe du programmeur qui passe ses nuits à programmer peut s'avérer exact chez certaines personnes, il n'en reste pas moins qu'après une dure journée de travail, on est quand même moins apte à résoudre des problèmes.<br />
<br />
<br />
<b><font size="3">1. Ne pas hésitez à utiliser du papier</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Schématisez vos pensées sur papier avant de vous jeter sur l'écran.
			
		</div>
	</div>
</div>Sur ce point, j'aurai tendance à dire, chacun ses préférences. Même si dans le fond, je suis d'accord qu'il est préférable de bien réfléchir au problème avant de coder. Cependant, le papier n'est pas l'unique possibilité. Il existe tout un tas d'outils (Mind Map, Power Point, ou même un simple éditeur de texte) qui peuvent permette de virtuellement griffonner ses idées, de se laisser à l'écriture libre, avant de mettre de l'ordre et les coder.<br />
<br />
<br />
<b><font size="3">2. La programmation doit devenir une habitude</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Planifiez des séances régulières de programmation
			
		</div>
	</div>
</div>Aucun doute là dessus. C'est en forgeant qu'on devient forgeron. Et c'est en forgeant davantage qu'on devient meilleur forgeron. Plus mes séances de programmation sont espacées et irrégulières, et plus il m'est difficile de me replonger sur un problème ou sur une technologie donnée. Je suis donc parfaitement d'accord sur ce point avec l'auteur.<br />
<br />
<br />
<b><font size="3">3. Notez vos idées tout comme vos bugs</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Ayez sur vous en permanence de quoi noter
			
		</div>
	</div>
</div>La mémoire humaine est relativement volatile et notre attention est sans cesse sollicitée pour de bonnes ou de mauvaises raisons. Quand une idée sur un projet que nous menons survient dans notre esprit, il est souhaitable d'avoir quelque chose pour noter et fixer cette idée. Après, je pense que de nos jours, avec les smartphones prêts à être dégainés à n'importe quelle occasion, ce n'est plus vraiment un problème, mais cela n'enlève en rien la réalité du propos.<br />
<br />
<br />
<b><font size="3">4. Faites vous des amis</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Exposer son code à la pression sociale et aux jugements des autres.
			
		</div>
	</div>
</div>Pour beaucoup d'entre nous il peut être plus motivant de savoir que ce qu'on fait sera jugé, apprécié ou pas, par d'autres. Bon après, votre entourage proche peut ne pas être réceptif du tout à la programmation et à l'informatique en général, mais il y a toujours les collègues ou encore les forums (dont developpez.com ^^). Cela peut être une puissante source de motivation de savoir que son projet peut susciter la curiosité et puisse éventuellement être suivi dans son évolution. Je ne peux que confirmer. Après, il est tout à fait possible que cette &quot;pression&quot; sociale puisse être intimidante et inhibitrice. Donc je me garderais bien de généraliser ce conseil à n'importe qui.<br />
<br />
<br />
<b><font size="3">5. Apprenez des autres</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Ne pas réinventer la roue
			
		</div>
	</div>
</div>Il est assez rare qu'on soit le seul et le premier à être confronté à un certain problème. D'autres sont certainement passés avant nous. Tout comme dans la littérature où il est très conseillé de lire pour écrire, cela est à mon sens encore plus vrai dans le domaine de la programmation. Mener à terme un projet d'envergure en partant de zéro est voué à l'échec. La connaissance des bibliothèques et des frameworks est devenue incontournable dans l'activité de développeur.<br />
<br />
<br />
<b><font size="3">6. Favorisez votre inspiration</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				L'environnement et les activités annexes ont leur importance
			
		</div>
	</div>
</div>Plutôt d'accord, même si la créativité dans la programmation, même si elle est indéniable, n'est pas tout à fait comparable à celle nécessaire dans l'écriture d'un roman. Donc, il faut être attentif à son cadre de travail, afin d'être dans des conditions propices à la créativité, ainsi qu'à s'ouvrir l'esprit à des activités tout à fait différentes. Restez curieux d'autant que c'est utile pour la vie en générale. Difficile donc d'être en désaccord sur ce point.<br />
<br />
<br />
<b><font size="3">7. Soyez sans pitié</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Retirer le superflu de votre code et remplacer du code obsolète par un autre meilleur
			
		</div>
	</div>
</div>Dans la programmation, disons que cela va de soi. Autant cela peut être difficile dans un roman où l'auteur peut avoir mis beaucoup de lui-même dans un chapitre ou dans une scène, autant l'affect moyen du programmeur envers un morceau de code est tout de même tout à fait relatif. Donc si jamais on trouve une meilleure solution (plus performante, moins gourmande en mémoire, plus fiable), il est naturel pour tout programmeur avec un minimum de conscience professionnelle de choisir cette solution au détriment du code existant, même si c'est le sien.<br />
<br />
<br />
<b><font size="3">8. Méfiez-vous de votre propre expertise</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Il est nécessaire que ceux qui liront votre code le comprenne
			
		</div>
	</div>
</div>Il est en effet indispensable autant pour les autres que pour soi-même de faire l'effort (car ça prend du temps) d'écrire du code propre, commenté, d'utiliser des noms de variables adéquats et expressifs. C'est à mon sens cette partie qui se rapprocherait le plus de la littérature. Car il est &quot;facile&quot; de coder, mais c'est plus difficile de faire comprendre le code à quelqu'un d'autre. Et pour qu'une application soit maintenable dans la durée et puisse évoluer avec l'intervention d'autres personnes, il faut rendre le code lisible, comme un roman doit être accessible à ses lecteurs.<br />
<br />
<br />
<b><font size="3">9. Finissez en haut d'un tobogan</font></b><br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				A chaque fin de journée, préparer la journée suivante
			
		</div>
	</div>
</div>C'est en effet une bonne manière de se mettre dans de bonnes prédispositions mentales pour attaquer une nouvelle journée. Si on a déjà prévue la veille de ce qu'il faut faire, la reprise le lendemain n'en sera que plus simple et rapide. Les To Do List, les commentaires (temporaires) dans le code, les post-its sur le bord de l'écran, ou mieux encore, un planning (à jour bien sûr...) sont des aides précieuses pour se fixer les objectifs du lendemain et garder la dynamique. La programmation, parce que ce n'est pas si simple exige un minimum d'organisation et de discipline. Mais ça, je suppose que vous le saviez ;)<br />
<br />
<br />
<b><font size="3">Conclusion</font></b><br />
<br />
Globalement, je suis donc d'accord avec l'auteur de l'article, sur de nombreux points. Écrivant des nouvelles en parallèle, il est vrai qu'il existe de nombreuses similitudes entre l'activité d'écrivain et de programmeur et que les techniques pour surmonter les blocages peuvent être transposables d'un domaine à l'autre. Cependant, il faut quand même résister à la tentation d'y voir deux activités totalement semblables. Il y a quand même des différences, et pas des moindres. Par exemple, l'originalité est souvent une qualité recherchée dans un roman, alors que ce n'est pas vraiment ce qui est demandé en premier à un programme où l'efficacité prime (&quot;It just works&quot;). D'où mes réserves quand à certains points mentionnés par l'auteur. Mais sinon, cette liste peut être une bonne aide lorsqu'on tombe en panne, non pas d'inspiration, mais au moins de motivation.<br />
<br />
Bon développement ! ;)</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b3392/surmonter-blocage-programmeur/</guid>
		</item>
		<item>
			<title>gpu.js : le JavaScript accéléré par la carte graphique</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b3369/gpu-js-javascript-accelere-carte-graphique/</link>
			<pubDate>Fri, 14 Jul 2017 23:58:47 GMT</pubDate>
			<description>Pièce jointe 294178...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p294178d1500075571/c-cpp/outils-c-cpp/visual-cpp/mfc/mschart/1024.png/" border="0" alt="Nom : 1024.png
Affichages : 22705
Taille : 17,1 Ko"  style="float: CONFIG" /></div><br />
Il se fait tard au moment où je tape ces quelques lignes, mais je viens de tomber sur quelque chose qui pourrait se révéler être un moyen d'optimisation très intéressant à l'heure où les applications JavaScript deviennent de plus en plus gourmandes en ressources de calcul. Le JavaScript étant principalement monothread et les calculs en JS étant pour une large part à l'heure actuelle synchrone, quand ils deviennent nombreux et complexes, ça peut devenir un problème comme dans le domaine des jeux vidéos, de la simulation numérique, du Big Data, de l'Intelligence Artificielle ou plus généralement du calcul scientifique qui commence à pointer le bout de son nez sur navigateur.<br />
<br />
Il se trouve qu'un composant existant sur de nombreux ordinateurs, la carte graphique, est justement spécialisée dans le calcul numérique avec l'avantage que ces calculs peuvent être exécutés en parallèle, ce qui change tout. Depuis quelques années déjà, il existait des solutions pour détourner l'usage premier de la carte graphique, afficher des pixels, pour en faire une unité de calcul à vocation généraliste, concept connu sous l'acronyme barbare de GPGPU. Mais c'était réservé à quelques langages comme le C++, Python ou la plateforme .NET. Pour les développeurs JavaScript, point de salut, cela restait un peu le vide intersidéral.<br />
<br />
Et bien, il se trouve que ce vide vient d'être comblé tout récemment puisqu'une bibliothèque du nom de <b>gpu.js</b> permet d'exécuter certains calculs sur la carte graphique et non pas sur le processeur principal qui sera ainsi libre de réagir aux interactions de l'utilisateur. Le champ d'action de cette bibliothèque est pour le moment assez restreint, mais elle n'en est qu'à sa version 0.0.Alpha. Il y a donc certainement de la marge de progression.<br />
<br />
Mais déjà, selon le benchmark fourni en guise de démonstration et mon PC portable au moment où j'écris, les calculs seraient accélérés d'un facteur trois avec le circuit intégré Intel HD Graphics et au delà d'un facteur 8 avec une véritable carte graphique. Loin d'être négligeable donc.<br />
<br />
Même si je n'ai pas encore vraiment pu regarder sous le capot, la bibliothèque doit sans doute générer des shaders à la volée qu'elle transmet ensuite à la carte graphique via la couche WebGL. A vérifier mais en gros, ça doit ressembler à quelque chose comme ça.<br />
<br />
Quoiqu'il en soit, cela ouvre des perspectives tout à fait intéressantes pour le langage JavaScript. Si on considère le projet WebAssembly et l'évolution de la norme vers le parallélisme et la concurrence (Web Workers et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">SharedArrayBuffer</span>), je vois mal ce qui ne pourra pas tourner à l'avenir sur le navigateur.<br />
<br />
N'hésitez pas à me dire ce que vous pensez de cette bibliothèque.<br />
<br />
Bon développement !<br />
<br />
:fleche: source : <a href="http://gpu.rocks/" target="_blank"><u>Site officiel</u></a></blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b3369/gpu-js-javascript-accelere-carte-graphique/</guid>
		</item>
		<item>
			<title>Comprendre les Promises en JavaScript / TypeScript</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b3285/comprendre-promises-javascript-typescript/</link>
			<pubDate>Mon, 26 Jun 2017 07:00:00 GMT</pubDate>
			<description>Pièce jointe 288914...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="https://www.developpez.net/forums/attachment.php?attachmentid=288914&amp;d=1498404537" border="0" alt="Nom : JS TS.png
Affichages : 76053
Taille : 7,3 Ko"  style="float: CONFIG" /></div><br />
Cet article a pour but de présenter un peu plus posément et en détail les Promises (ou Promesses en français), un concept qui avait été déjà abordé dans un article que j'avais traduit en 2015 : <a href="https://javascript.developpez.com/actu/90964/JavaScript-et-le-futur-de-l-asynchrone-un-article-de-David-Catuhe-traduit-par-yahiko/" target="_blank"><u>Le futur de l'asynchrone en JavaScript</u></a>.<br />
<br />
Je pense que c'est d'autant plus intéressant que la norme ES2015 (ou ES6) s'est depuis largement diffusée côté navigateurs, serveurs, transpileurs et développeurs au point que les Promises sont devenues un élément central de la programmation asynchrone sur lequel d'autres fonctionnalités de la norme ECMAScript se construisent, comme <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span>/<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">await</span>.<br />
<br />
Bien que les exemples dans cet article soient rédigés en TypeScript, les différences avec JavaScript ne concernent que les annotations de typage qui peuvent être vues ici comme de la documentation supplémentaire. Cela ne devrait pas gêner la compréhension de quelqu'un habitué à JavaScript.<br />
<br />
<br />
<font size="4"><b>1. Traitements asynchrones et callbacks</b></font><br />
<br />
JavaScript est un langage fonctionnel reposant sur une architecture asynchrone (cf. <a href="https://www.developpez.net/forums/blogs/676693-yahiko/b1546/bases-lasynchrone-javascript/" target="_blank"><u>Les bases de l'asynchrone en JavaScript</u></a>). Il n'est donc pas surprenant qu'historiquement, l'appel à des traitements asynchrones se faisait à l'aide de callbacks, ces fonctions passées en argument, permettant de poursuivre l'exécution du programme suite à la réalisation du traitement asynchrone.<br />
<br />
Il existe de nombreuses fonctions asynchrones dans les API JavaScript, la plus connue étant sans doute <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">XMLHttpRequest.send()</span>, mais pour des questions pratiques et pédagogiques, nous allons nous construire notre propre fonction asynchrone qui simulera la récupération d'une donnée sous la forme d'un nombre.<br />
<br />
Cette fonction asynchrone faite maison est nommée de façon très imaginative <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span>. Elle produit un nombre aléatoire qui sera ensuite transmis à la fonction callback préalablement passée en argument. Et pour simuler les erreurs éventuelles pouvant survenir durant un traitement asynchrone, cette fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> « plante » aléatoirement dans 25 % des cas.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;font-weight:bold">type</span> Callback <span style="color: black;">=</span> <span style="color: black;">&#40;</span>error<span style="color: black;">?:</span> Error<span style="color: black;">,</span> data<span style="color: black;">?:</span> <span style="color: #0080ff;">number</span><span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">function</span> getData<span style="color: black;">&#40;</span>callback<span style="color: black;">:</span> Callback<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    setTimeout<span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">function</span> setTimeoutCB<span style="color: black;">&#40;</span>counter<span style="color: black;">:</span> <span style="color: #0080ff;">number</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: black;">&#40;</span><span style="color: #0080ff;">Math</span>.<span style="color: #0080ff;">random</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&lt;</span> <span style="color: #cc66cc;">0.25</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
            callback<span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">new</span> Error<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Error in retrieving data.&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span>
        <span style="color: #0000ff;">else</span> <span style="color: black;">&#123;</span>
            <span style="color: #0000ff;font-weight:bold">let</span> data <span style="color: black;">=</span> <span style="color: #0080ff;">Math</span>.<span style="color: #0080ff;">random</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
            callback<span style="color: black;">&#40;</span><span style="color: #339933;">undefined</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">,</span> <span style="color: #cc66cc;">500</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span> <span style="color: #808080;">// getData</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Définition de la fonction asynchrone getData()</i></div><br />
On notera que cette fonction asynchrone <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> utilise une convention largement répandue en JavaScript qui est souvent nommée le <i>callback pattern</i> reposant sur les quatre principes suivants :<br />
<ul><li style="">une seule fonction callback gérant à la fois le succès et l'échec ;</li><li style="">la fonction callback est appelée une et une seule fois. Soit en cas de succès ou d'échec ;</li><li style="">la fonction callback est le dernier argument de la fonction asynchrone ;</li><li style="">le premier paramètre de la fonction callback représente l'erreur, le second représente le résultat en cas de succès : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">function (error, result) { ... }</span></li></ul><br />
<br />
Dans le cadre de cet exemple, la récupération des données se fait via un appel à cette fonction. Nous supposerons ici trois traitements successifs, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process1()</span>, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process2()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process3()</span>, chacun récupérant une donnée à l'aide de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span>. Voici à quoi pourrait ressembler la fonction du premier traitement :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:156px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;font-weight:bold">function</span> process1<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    getData<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>error<span style="color: black;">,</span> data<span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: black;">&#123;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 1:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            process2<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span> <span style="color: #808080;">// process1</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Définition du premier traitement</i></div><br />
Il s'agit évidemment d'un exemple minimaliste, car on remarque que cette fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process1()</span> ne fait pas grand-chose à part gérer un éventuel cas d'erreur, afficher la donnée récupérée via <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> et appeler le traitement suivant, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process2()</span>.<br />
<br />
Les fonctions pour les deux autres traitements sont très similaires :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;font-weight:bold">function</span> process2<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    getData<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>error<span style="color: black;">,</span> data<span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: black;">&#123;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 2:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            process3<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span> <span style="color: #808080;">// process2</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">function</span> process3<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    getData<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>error<span style="color: black;">,</span> data<span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: #0000ff;">else</span> <span style="color: black;">&#123;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 3:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span> <span style="color: #808080;">// process3</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Définition des deux autres traitements</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:72px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0">Process 1: 0.062177133421918995
Process 2: 0.2886812664927907
Process 3: 0.2154450024357153</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple de sortie sans erreur</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:108px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td valign="top"><pre style="margin: 0">Process 1: 0.41092615721662096
Error: Error in retrieving data.
    at Timeout.setTimeoutCB [as _onTimeout] (callback.js:13:22)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple de sortie avec erreur</i></div><br />
La fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process2()</span> appelle <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> puis enchaîne sur la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process3()</span> qui appelle à son tour <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> pour enfin conclure l'exécution du programme.<br />
<br />
Cette façon de programmer des appels à des fonctions asynchrones est très classique. Il se trouve que dans cet exemple, simplifié à l'extrême, cela ne pose pas de problème particulier, mais il suffit que le code soit un peu plus gros, avec des fonctions d'appel dans le désordre et disséminées dans plusieurs fichiers source pour aboutir à ce qui est communément appelé la programmation spaghetti et qui est avec la « pyramide de la mort » (succession excessive d'indentations), le principal symptôme de « l'enfer des callbacks ».<br />
<br />
Ça peut vite partir dans tous les sens et peut donner la migraine lorsqu'il s'agit de déboguer ou de retoucher le code.<br />
<br />
C'est là qu'entre en jeu un nouveau concept, les Promises.<br />
<br />
<br />
<font size="4"><b>2. La promesse des Promises</b></font><br />
<br />
Il y a mille et une manières d'expliquer ce que sont les Promises, concept un peu mystérieux au premier abord. Plutôt que d'employer des métaphores, parfois déroutantes et trompeuses, je pense que le plus simple est de présenter les choses sous un angle concret et de ne pas trop se focaliser sur le terme en lui-même.<br />
<br />
Une Promise est la transformation d'une fonction asynchrone en un objet (au sens JavaScript du terme) afin de faciliter la manipulation de ladite fonction asynchrone. Dans le domaine de la programmation, cette transformation d'une fonction en un objet est parfois appelée réification. C'est d'ailleurs un <i>design pattern</i> puissant.<br />
<br />
Dans notre exemple, il s'agit donc de transformer notre fonction asynchrone <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> en un objet de type Promise. Pour se faire, la norme ES2015 propose un constructeur de la forme suivante :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:72px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;font-weight:bold">new</span> Promise<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>resolve<span style="color: black;">,</span> reject<span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
 <span style="color: #808080;">/* appel &agrave; la fonction asynchrone */</span>
<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
On notera que la forme ci-dessus n'est pas typée pour des raisons de clarté, une version typée est indiquée un peu plus loin.<br />
<br />
Le constructeur d'une Promise prend en paramètre une fonction, désignée par convention comme « l'exécuteur ». Cet exécuteur prend deux fonctions en argument : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject</span>. La fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> sera appelée en cas de succès de la fonction asynchrone, tandis que la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> sera appelée en cas d'échec.<br />
<br />
Dans le cadre de notre exemple avec <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span>, cela pourrait ressembler à ceci :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;font-weight:bold">type</span> PromiseResolve<span style="color: black;">&lt;</span>T<span style="color: black;">&gt;</span> <span style="color: black;">=</span> <span style="color: black;">&#40;</span>value<span style="color: black;">?:</span> T <span style="color: black;">|</span> PromiseLike<span style="color: black;">&lt;</span>T<span style="color: black;">&gt;</span><span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span>
<span style="color: #0000ff;font-weight:bold">type</span> PromiseReject <span style="color: black;">=</span> <span style="color: black;">&#40;</span>error<span style="color: black;">?:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">function</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;font-weight:bold">new</span> Promise<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>resolve<span style="color: black;">:</span> PromiseResolve<span style="color: black;">&lt;</span>number<span style="color: black;">&gt;,</span> reject<span style="color: black;">:</span> PromiseReject<span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">void</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
        getData<span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>error<span style="color: black;">,</span> data<span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
            <span style="color: #0000ff;">if</span> <span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span> reject<span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span>
            <span style="color: #0000ff;">else</span> resolve<span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span> <span style="color: #808080;">// getDataPromise</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Réification de la fonction asynchrone</i></div><br />
Ci-dessus, la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getDataPromise()</span> génère une Promise de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span>. On peut constater que la fonction callback passée en argument de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> appelle <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> en cas d'erreur, et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> si tout se passe correctement.<br />
<br />
Pour appeler notre fonction asynchrone <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> à partir de cet objet généré par le constructeur <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">new Promise()</span>, nous pouvons utiliser une méthode nommée <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> de la façon suivante :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:108px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td valign="top"><pre style="margin: 0">getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
    data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
        console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 1:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: #0000ff;">return</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#41;</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Appel de la fonction asynchrone via la méthode then()</i></div><br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> va appeler l'exécuteur de la Promise qui lui-même appellera la fonction asynchrone. Cette méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> prend en théorie deux paramètres, le second étant optionnel. Ces paramètres correspondent respectivement à la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> qui seront transmis à l'exécuteur. Dans l'exemple ci-dessus, seul le paramètre correspondant à la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> a été spécifié.<br />
<br />
À noter qu'il n'est pas obligatoire de spécifier la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> dans l'appel à la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span>, c'est même déconseillé. Si une erreur survient et que la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> n'est pas spécifiée, alors une exception sera signalée qui pourra être récupérée ultérieurement via une autre méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch()</span>.<br />
<br />
Avant de poursuivre, voici un petit récapitulatif des notions abordées autour des Promises :<br />
<ul><li style="">Fonction asynchrone : fonction dont on souhaite obtenir un résultat ;</li><li style="">Promise : réification de la fonction asynchrone ;</li><li style="">Exécuteur de la Promise : fonction appelée, entre autres, via la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> de la Promise et chargée d'appeler la fonction asynchrone ;</li><li style=""><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve</span> : fonction appelée en cas de succès de la fonction asynchrone ;</li><li style=""><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject</span> : fonction appelée en cas d'échec de la fonction asynchrone ;</li><li style=""><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then</span> : méthode de la Promise pour appeler l'exécuteur.</li></ul><br />
<br />
Comme on l'a vu précédemment, transformer une fonction asynchrone en Promise (on lit parfois « promissification ») consiste en deux étapes :<br />
<ul><li style=""> réifier la fonction asynchrone via le constructeur de Promise en prenant soin d'écrire l'exécuteur de la fonction asynchrone de telle sorte qu'il appelle la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> en cas de succès, et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> en cas d'échec ;<br /></li><li style=""> l'appel de la fonction asynchrone peut se faire via la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> de la Promise nouvellement créée. C'est dans l'appel à cette méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> que se définissent concrètement les fonctions auxiliaires <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span>, et qui seront appelées par l'exécuteur de la fonction asynchrone.</li></ul><br />
<br />
<br />
<font size="4"><b>3. Composition de Promises</b></font><br />
<br />
L'état d'une Promise peut évoluer au cours de son existence.<br />
<br />
Lors de sa création, une Promise est dans un état « en attente » (<i>pending</i>), sous-entendu, en attente d'être résolue.<br />
Lorsque la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> de cette Promise est appelée, son état devient soit honoré (<i>fullfilled</i>) en cas de succès du traitement asynchrone sous-jacent, ou rompu (<i>rejected</i>) en cas d'échec. Une Promise honorée ou rompue est une Promise acquittée (<i>settled</i>) ou encore résolue, bien que ce dernier terme puisse porter à confusion avec la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span> qui correspond à une Promesse honorée uniquement.<br />
<br />
Pour une Promise prise isolément, ces changements d'état n'ont pas une grande importance. Ce n'est plus le cas lorsqu'il s'agit de chaîner, de composer plusieurs Promises entre elles.<br />
<br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> renvoyant elle-même une Promise, il est possible d'enchaîner les appels à cette méthode.<br />
<br />
Dans le cadre de notre exemple, on aurait pu écrire le code suivant :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td valign="top"><pre style="margin: 0">getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 1:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            <span style="color: #0000ff;">return</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">,</span>
        error <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// reject()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 2:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            <span style="color: #0000ff;">return</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">,</span>
        error <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// reject()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 3:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">,</span>
        error <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// reject()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
<span style="color: black;">;</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Composition d'appels de la méthode then() à deux arguments (non recommandé)</i></div><br />
On notera tout d'abord la ressemblance, voulue, avec les fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process1()</span>, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process2()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">process3()</span> du chapitre 2 sur les fonctions callback, sauf qu'ici il n'a pas été nécessaire de créer ces fonctions intermédiaires, limitant ainsi le recours au code spaghetti, tout en évitant la « pyramide de la mort ».<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:72px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0">Process 1: 0.9523288000061796
Process 2: 0.7071524761970143
Process 3: 0.31277126054349025</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple de sortie sans erreur avec la méthode then() à deux arguments</i></div><br />
Ensuite, on remarquera le renvoi d'une nouvelle Promise (<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">return getDataPromise()</span>) dans les deux premiers appels à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span>, dans la partie dédiée à la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">resolve()</span>. C'est le fait de retourner une nouvelle Promise qui permet à l'appel à la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> suivante de produire un nouveau résultat, ici un nombre aléatoire. Sans cela, le second et le troisième appel à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span> opéreraient sur une Promise déjà acquittée, issue du premier appel à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span>, avec un résultat non défini (<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">undefined</span>).<br />
<br />
C'est d'ailleurs ce qui se passe dans le code ci-dessus en cas d'erreur. La partie correspondant à la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> ne renvoie pas de nouvelle Promise.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:120px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td valign="top"><pre style="margin: 0">Process 1: 0.6955174514497151
Error: Error in retrieving data.
    at Timeout.setTimeoutCB [as _onTimeout] (promise.js:13:22)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)
Process 3: undefined</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple de sortie avec erreur avec la méthode then() à deux arguments</i></div><br />
On notera dans l'exemple de sortie ci-dessus la valeur <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">undefined</span> au niveau du Process 3.<br />
<br />
Le code produit plus haut ne se comporte donc pas tout à fait comme son homologue avec les fonctions callback classiques. Ici, une erreur n'empêche pas la poursuite des appels.<br />
<br />
Il est assez rare que cela soit un comportement souhaité, et comme vu dans le chapitre précédent, il est déconseillé de spécifier la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span> lors de l'appel à la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span>. Il faut préférer l'utilisation d'une autre méthode, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch()</span>, qui n'est qu'en fait une version simplifiée de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span>, ne prenant qu'un seul argument, la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">reject()</span>.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0">getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 1:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            <span style="color: #0000ff;">return</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 2:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            <span style="color: #0000ff;">return</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// resolve()</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Process 3:&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0000ff;">catch</span><span style="color: black;">&#40;</span>error <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span> <span style="color: #808080;">// reject()</span>
        console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
<span style="color: black;">;</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Composition d'appels de la méthode then() à un seul argument, avec la méthode catch() (recommandé)</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:72px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br /></div></td><td valign="top"><pre style="margin: 0">Process 1: 0.29398199861957175
Process 2: 0.9661893214860926
Process 3: 0.9223972522278627</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple de sortie sans erreur avec la méthode catch()</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:108px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td valign="top"><pre style="margin: 0">Process 1: 0.20758402318588276
Error: Error in retrieving data.
    at Timeout.setTimeoutCB [as _onTimeout] (promise.js:13:22)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple de sortie avec erreur avec la méthode catch()</i></div><br />
Lorsqu'une erreur se produit, celle-ci se propage de façon descendante jusqu'à la première méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch()</span> trouvée. La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch()</span> peut apparaître tout au long de la chaîne, à condition que les <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch()</span> intermédiaires prennent soin de propager l'erreur tout au long de la chaîne à l'aide de l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">throw</span>. Cela peut être utile pour gérer les erreurs dès qu'elles surviennent, dans une logique de travail en équipe où chaque développeur est responsable de la gestion des erreurs de son domaine fonctionnel, et aussi pour éviter d'avoir un gros <i>switch</i> dans le <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch()</span> final. Il y aurait beaucoup à dire sur la manière de gérer les erreurs avec les Promises, mais cela dépasserait probablement le cadre de cette introduction.<br />
<br />
Il est possible de combiner les Promises autrement qu'avec <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">then()</span>. Présentons deux autres méthodes standards offertes dans la norme ES2015 : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">all()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">race()</span>.<br />
<br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">all()</span> prend en paramètres une séquence de Promises et renvoie une Promise qui est honorée si et seulement si toutes les Promises passées en paramètres sont honorées également. La valeur finale étant un tableau des valeurs des Promises honorées. Dans le cas contraire, si au moins l'une des Promises passées en paramètres a été rompue, alors la Promise renvoyée par la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">all()</span> sera rompue également. En gros, c'est tout ou rien.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0">Promise.<span style="color: #0080ff;">all</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">,</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">,</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Success!&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0000ff;">catch</span><span style="color: black;">&#40;</span>error <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
        console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
<span style="color: black;">;</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple d'utilisation de la méthode all()</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:36px;">Success! [ 0.5930896059730313, 0.4881301731930028, 0.338379519116232 ]</pre>
</div><div style="text-align: center;"><i>Exemple de sortie sans erreur de la méthode all()</i></div><br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">race()</span> quant à elle prend également en paramètres une séquence de Promises et renvoie une Promise qui est honorée si au moins une des Promises passées en paramètres a été honorée. La valeur prise en compte étant celle de la première Promise à avoir été honorée, d'où le nom « race » (course en français). Ce n'est que si toutes les Promises passées en paramètres ont été rompues que la Promise renvoyée par <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">race()</span> sera rompue.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0">Promise.<span style="color: #0080ff;">race</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">,</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">,</span> getDataPromise<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0080ff;">then</span><span style="color: black;">&#40;</span>
        data <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
            console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Success!&quot;</span><span style="color: black;">,</span> data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
    .<span style="color: #0000ff;">catch</span><span style="color: black;">&#40;</span>error <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
        console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>error<span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
<span style="color: black;">;</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Exemple d'utilisation de la méthode race()</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:36px;">Success! 0.2673875038150235</pre>
</div><div style="text-align: center;"><i>Exemple de sortie sans erreur de la méthode race()</i></div><br />
<br />
<font size="4"><b>4. Conclusion</b></font><br />
<br />
Terminons cet article sur quelques considérations de compatibilité. Si votre plateforme cible ne supporte pas les Promises (et plus généralement la norme ES2015), il est possible d'avoir recours à un polyfill. Il en existe de nombreux sur la toile, 100 % compatibles avec la norme ES2015. Il y a aussi le transpilateur Babel qui inclut un polyfill pour les Promises.<br />
<br />
Pour compiler du code TypeScript en ES5 tout en utilisant les Promises, il convient d'utiliser un polyfill tiers comme indiqué précédemment, et d'inclure la bibliothèque <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">es2015.promise</span> dans l'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">lib</span> du fichier de projet <i>tsconfig.json</i>.<br />
<br />
Comme on vient de le voir, les Promises sont une avancée très appréciable pour mieux structurer son code asynchrone, et ceci au prix d'une abstraction somme toute minime. La conversion à partir du <i>callback pattern</i> historique est relativement directe. Cependant, même si le code résultant est davantage linéaire, il reste encore assez éloigné à du code synchrone, impératif, en général plus facile à appréhender. Mais ça, c'est le rôle des instructions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span>/<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">await</span> initialement prévues pour la version ES2016, mais reportées pour cette année 2017, et qui pourront faire l'objet d'un article dédié.</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b3285/comprendre-promises-javascript-typescript/</guid>
		</item>
		<item>
			<title><![CDATA[[DevLog] Clash of the Daemons : la pelote et l'incident]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1621/devlog-clash-of-the-daemons-pelote-l-incident/</link>
			<pubDate>Fri, 09 Sep 2016 10:23:15 GMT</pubDate>
			<description><![CDATA[*[DevLog] Clash of the...]]></description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><font size="3"><b>[DevLog] Clash of the Daemons : la pelote et l'incident</b></font><br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p219970d1473416413/c-cpp/c/bibliotheques-systemes-outils/posix/fork-sous-windows/demonface-furry.png/" border="0" alt="Nom : demonFace-Furry.png
Affichages : 3921
Taille : 254,5 Ko"  style="float: CONFIG" /></div><br />
J'ai décidé de poursuivre la <b><u><a href="http://www.developpez.net/forums/blogs/676693-yahiko/b1603/clash-of-the-daemons/" target="_blank">démo</a></u></b> développée pour le week-end du jeu vidéo en août dernier, ce qui donnera lieu à des compte-rendus réguliers, du moins je l'espère, sur l'avancement de ce petit projet.<br />
<br />
<font size="4"><b>Le syndrome de la pelote de laine</b></font><br />
<br />
Dans un <u><b><a href="http://www.developpez.net/forums/blogs/676693-yahiko/b1608/conseils-generaux-processus-developpement-solo-jeu/" target="_blank">article</a></b></u> que j'ai traduit et récemment publié sur mon blog, Macoy Madson appelle le « Mur » ce moment fatidique où il devient très difficile, voire impossible, d'avancer sur son projet de jeu vidéo. Sauf à se mentir, quiconque s'est lancé dans l'aventure a un jour dû faire face à ce phénomène. Bien que l'image du « Mur » soit tout à fait représentative sur les conséquences du problème, à savoir le blocage presque systématique qui se produit au cours du développement solo d'un jeu vidéo, quand on est amateur, il n'explique pas vraiment la réelle nature de ce problème. Ça tombe bien, comme je suis à peu près en plein dedans, je vais essayer d'expliciter de quoi il en retourne.<br />
<br />
L'une des caractéristiques du jeu vidéo par rapport à d'autres applications dites transactionnelles, est le degré d'interconnexion, pour ne pas dire d'intrication entre ses différentes composantes. Ce phénomène apparaît passé un certain stade, après avoir implémenté les traitements de bas niveau relativement linéaires et isolés comme le rendu graphique ou la gestion du contrôleur. Lorsqu'il s'agit d'implémenter les concepts liés au gameplay (eg. les interactions entre le joueur et son environnement ou le système d'IA), ce qu'on nommerait dans le monde de l'entreprise par les « règles de gestion » ou les « règles métiers », on ressent vite le besoin de relier, de faire communiquer, divers composants, d'une façon ou d'une autre. C'est à ce moment qu'on a recourt à diverses techniques de l'ingénierie du logiciel par exemple l'héritage par classe, par prototype, la composition, le <i>pattern</i> observateur, la file de messages, les fabriques (<i>factories</i>), les architectures MVC, MVVM et j'en passe. Quand ces termes apparaîssent dans l'esprit d'un développeur, c'est souvent le signe du début des réelles complications en général... Il va il y avoir du sport !<br />
<br />
Évidemment, le code spaghetti qui a peut-être servi en tout début de projet pour réaliser les premiers prototypes montre à ce stade toutes ses limites. Lorsque les relations entre les composants d'une application se complexifient, et ça se produit toujours dans le cas d'un jeu vidéo (hormis les genres trivaux du style morpion ou <i>Pong</i>), le code spaghetti nous empêche d'y voir clair. C'est un obstacle majeur à l'ordre que nous cherchons à mettre en place. Ordre nécessaire pour faciliter le raisonnement sur le code, notamment lorsque des bugs se produisent ou lorsqu'on cherche à enrichir le gameplay, ce qui en phase de développement se produit fréquemment, cela va sans dire.<br />
<br />
Tout un arsenal de techniques ont été mises au point pour <i>déspaghettifier</i> le code, d'où l'apparition du terme un peu pompeux de <i>design pattern</i>. Cependant, même si ces <i>design patterns</i> permettent de dépasser les défauts du code spaghetti, ils ne peuvent pas fondamentalement réduire la complexité intrinsèque du réseau de relations entre les multiples composants d'un jeu vidéo, sauf à revoir les exigences de gameplay à la baisse...<br />
<br />
C'est cette complexité intrinsèque liée au <i>gameplay</i>, souvent sous-estimée par les débutants qui est selon moi la principale cause du « Mur » que décrit Macoy Madson. C'est d'ailleurs la raison pour laquelle, il est souvent préférable quand on débute, de s'attaquer aux parties les plus « linéaires » d'un jeu vidéo comme le rendu graphique. Cela a l'avantage de produire rapidement des résultats qui sont visibles. (Il n'en reste pas moins que produire un bon moteur graphique en partant de zéro reste tout de même un travail de longue haleine, qu'il n'y ait pas de méprise). Avoir rapidement un feedback visuel, c'est plus motivant que de se battre à déboguer des logiques de gameplay qui ne produiront pas forcément d'effets visibles.<br />
<br />
En pratique, la complexité intrinsèque liée au gameplay se traduit souvent par ce que je nommerai « le syndrome de la pelote de laine ». Et je viens de l'expérimenter tout dernièrement pendant le développement de <i><b>Clash of the Daemons</b></i>...<br />
<br />
Concrètement, je souhaitais améliorer à la marge un des comportements des PNJ, le « <i>hit-and-run »</i>, dont le <i>pattern</i> peut être globalement décomposé en trois phases : la poursuite vers la cible (ie. le joueur), l'attaque au corps-à-corps, et la fuite.<br />
<br />
Sans rentrer dans les détails au risque de devenir rasoir, ce comportement est lié au module d'IA d'une part et d'autre part au concept d'attaque. Pour améliorer le « <i>hit-and-run »</i>, même modestement, j'ai été amené à :<br />
<br />
<ul><li style="">remodeler sensiblement mon module d'IA,</li><li style="">ajouter une gestion d'inventaire,</li><li style="">ajouter le concept d'arme,</li><li style="">et changer le gameplay pour basculer de l'attaque à distance vers l'attaque au corps-à-corps et vice-et-versa. </li></ul><br />
 <br />
Cela a même impacté le mapping des touches du joueur alors qu'il s'agissait à la base d'une modification d'un comportement de PNJ !<br />
<br />
Un long détour qui peut décourager au premier abord. Mais même si au final cela n'a rien donné de très visible à l'écran, ces grosses modifications internes permettent au code d'être plus évolutif et donnent surtout de nouvelles possibilités pour le gameplay. Par exemple, désormais, je peux sereinement envisager d'avoir un nombre arbitraire d'armes aux effets variés, sans craindre de manquer de touches pour le joueur et sans modifier les classes existantes. Et concernant l'IA, grâce au remodelage, il devient très facile de combiner les comportements pour en produire un nouveau, à la manière des legos, chose qui n'était pas garantie précédemment.<br />
<br />
En souhaitant apporter une modification relativement mineure sur le plan fonctionnel, je me suis donc retrouvé à modifier une large portion de mon code, un peu à l'image d'une pelote de laine qu'on dévide au fur et à mesure sans savoir quand on va tomber sur l'autre extrémité. Il y a clairement un effet tunnel où on s'embarque dans un voyage dont on ne connaît pas encore la durée et sans avoir le feedback visuel gratifiant qu'on peut avoir quand on travaille sur les graphismes ou l'animation.<br />
<br />
Il ne faut donc pas sous-estimer la difficulté d'implémenter le gameplay, car de là surgit souvent le « Mur ». Il est possible de contourner le problème en restreignant le gameplay, ce qui peut tout à fait se justifier selon les situations. Cependant, si on souhaite conserver ses idées de gameplay, il faudra tout d'abord s'armer de patience et de courage, dévider petit à petit la pelote de laine (un outil de versionning comme Git est ici très utile pour sécuriser les innombrables refactoring qui interviendront), pour enfin briser le mur et en viser un autre. Car c'est un processus sans fin, ou presque ! En Asie, il existe un proverbe, « Après la montagne, la montagne ». C'est ce qu'il se produit quand on se lance dans le développement d'un jeu vidéo en solo : une succession continue d'obstacles à abattre.<br />
<br />
Surtout que ces obstacles peuvent survenir de n'importe où et à n'importe quel moment, pour preuve...<br />
<br />
 <br />
<font size="4"><b>L'incident OneDrive</b></font><br />
<br />
L'ensemble de mes projets personnels sont synchronisés avec mon compte OneDrive, l'offre de <i>cloud</i> de Microsoft. Cela permet de bénéficier gratuitement d'une sauvegarde hors-les-murs avec un bon niveau de service. Du moins en théorie car depuis que j'ai appliqué la mise à jour <i>Anniversaire</i> de Windows 10, le processus OneDrive tend à perdre les pédales en se lançant par exemple en trois, quatre voire cinq exemplaires, ou bien en moulinant dans le vide. Mais à vrai dire, je ne m'en étais jusqu'à présent pas trop inquiété, après tout, du moment que la sauvegarde est faite sur le <i>cloud</i>, c'est bien le principal, n'est-ce pas ?<br />
<br />
Il se trouve qu'il y a quelques jours, en ouvrant mon projet dans Visual Studio Code, le référentiel Git était corrompu. De plus, une moitié de mes sources avaient disparu, et l'autre semblaient complètement obsolète, <i>out of date</i> dirait-on en anglais. OneDrive semblait avoir fait des siennes en synchronisant (ou plutôt en désynchronisant) d'une curieuse façon les données du <i>cloud</i> vers mon disque en local. En gros, des dizaines et des dizaines d'heures de travail venaient de partir en fumée... C'est dans ces moments un peu désespérés, bien que rares toutefois, où on se bénit soi-même d'avoir mis en place une sauvegarde incrémentale sur autre disque dur. Je n'ai heureusement ainsi perdu que le delta depuis ma dernière sauvegarde, ce qui ne représentait que moins d'une heure (la sauvegarde est planifiée toutes les heures). C'est beaucoup plus acceptable que 50 heures de perdues !<br />
<br />
Moralité : Même sur des projets personnels, ne jamais négliger la sécurité des données en doublant voire triplant les procédés de sauvegarde. Car dans mon cas, c'est bien un outil sensé garantir ces données, en l'occurrence OneDrive, qui a causé la perte d'une partie de ces données. Mais comme toutes les bonnes histoires, ça se termine sur un <i>happy end</i>. ;)</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1621/devlog-clash-of-the-daemons-pelote-l-incident/</guid>
		</item>
		<item>
			<title>Paon : le design pattern Observateur sans héritage en TypeScript / JavaScript</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1616/paon-design-pattern-observateur-heritage-typescript-javascript/</link>
			<pubDate>Sun, 04 Sep 2016 20:39:34 GMT</pubDate>
			<description>*Paon : le design pattern...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><b><font size="3">Paon : le design pattern Observateur sans héritage en TypeScript / JavaScript</font></b><br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p219594d1473021567/applications/developpement-2d-3d-jeux/api-graphiques/directx/reserver-zone-l-ecran-mode-plein-ecran/typescript.png/" border="0" alt="Nom : TypeScript.png
Affichages : 3537
Taille : 1,8 Ko"  style="float: CONFIG" /></div><br />
<b><font size="4">Introduction</font></b><br />
<br />
Le <i>design pattern</i> (patron de conception) <b>Observateur</b> est omniprésent de nos jours. Que ce soit en programmation événementielle, avec les architectures MV* style Angular et la problématique du <i>data-binding</i>, la programmation dite <i>reactive</i> ou encore en conjonction avec l'approche <i>Entity-Component-Systems</i>.<br />
<br />
Ce billet n'a pas pour ambition de vous expliquer en détail le <i>design pattern</i> Observateur, ce pourrait faire l'objet d'un article indépendant, mais de vous présenter une petite bibliothèque de mon cru qui implémente ce <i>design pattern</i> de façon légèrement différente de ce qui est usuel de rencontrer.<br />
<br />
Cette bibliothèque nommée <b>Paon</b> (comme l'oiseau) a la modeste ambition de répondre à différents objectifs :<br />
<ul><li style="">Être sans dépendance</li><li style="">Être simple à utiliser</li><li style="">Être généraliste et non rattaché à une architecture (notamment MV*)</li><li style="">Ne pas contraindre la structure des objets à observer via l'héritage que ce soit par classe ou par interface</li><li style="">Faire appel à des observateurs sous la forme de fonctions</li></ul><br />
<br />
De ces contraintes a résulté la bibliothèque <b>Paon</b> qui en est à sa version 0.2.2 et que vous pouvez récupérer sur mon <u><b><a href="https://github.com/yahiko00/Paon" target="_blank">compte GitHub</a></b></u> ou via <u><b><a href="https://www.npmjs.com/package/paon" target="_blank">npm</a></b></u>.<br />
<br />
A noter que bien qu'étant rédigée en TypeScript, cette bibliothèque peut être utilisée par des applications JavaScript (cf. répertoire <i>dist/</i>).<br />
<br />
Cette bibliothèque est en <i>open source</i> sous licence MIT.<br />
<br />
En espérant que cette bibliothèque pourra vous être utile. N'hésitez pas à me faire part de vos retours d'expérience et à la partager autour de vous.<br />
<br />
<br />
Ce qui suit est la traduction en français de sa description en anglais.<br />
<br />
<b><font size="4">Paon</font></b><br />
<br />
Un composant Observateur en TypeScript/JavaScript.<br />
<br />
<ul><li style="">Pas d'héritage requis.</li><li style="">L'observable est juste un composant à l'intérieur d'un objet.</li><li style="">Les observateurs sont juste des fonctions.</li></ul><br />
<br />
<br />
<b><font size="3">Installation</font></b><br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install paon</span></div><br />
Pour compiler le source TypeScript en JavaScript, vous pourriez avoir besoin d'installer le compilateur <b>TypeScript</b> :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install -g typescript</span></div><br />
Pour générer la version JavaScript minifiée lors du <i>build</i>, vous pourriez avoir besoin d'installer <b>uglifyjs</b> :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install -g uglifyjs</span></div><br />
<br />
<b><font size="3">Build</font></b><br />
Les fichiers résultants sont créés dans le répertoire <i>dist/</i>.<br />
<br />
Build complet (compilation et minification):<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm run build</span></div><br />
Simple compilation (pas de minification):<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm run compile</span></div><br />
<br />
<b><font size="3">Utilisation</font></b><br />
<br />
Toutes les constantes, interfaces, classes et fonctions sont accessibles au sein de l'espace de nommage <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Paon</span>.<br />
<br />
<b><font size="2">Exemple simple</font></b><br />
<br />
Voici un exemple simple où nous ajoutons le composant <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">observable</span> à l'intérieur de notre classe <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Subject</span> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">/// &lt;reference path=&quot;paon.d.ts&quot; /&gt;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">class</span> Subject <span style="color: black;">&#123;</span>
	<span style="color: #0000ff;font-weight:bold">private</span> name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
	observable<span style="color: black;">:</span> Paon.<span style="color: #0080ff;">Observable</span><span style="color: black;">;</span> <span style="color: #808080;">// Composant Observer Pattern</span>
&nbsp;
	<span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">observable</span> <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Paon.<span style="color: #0080ff;">Observable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// Instanciation / Initialisation</span>
	<span style="color: black;">&#125;</span>
&nbsp;
	changeName<span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#123;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">observable</span>.<span style="color: #0080ff;">notifyObservers</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;nameChanged&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// Un message est envoy&eacute; aux observateurs</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span><span style="color: black;">;</span>
	<span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">function</span> onNameChanged<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
	alert<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Name has changed&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">let</span> subject <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Subject<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Penelope&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
subject.<span style="color: #0080ff;">observable</span>.<span style="color: #0080ff;">addObserver</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;nameChanged&quot;</span><span style="color: black;">,</span> onNameChanged<span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// La fonction onNameChanged() souscrit aux messages &quot;nameChanged&quot; du sujet</span>
&nbsp;
subject.<span style="color: #0080ff;">changeName</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Melissa&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: #808080;">// Une popup d'alerte appara&icirc;t: &quot;Name has changed&quot;</span></pre></td></tr></table></pre>
</div><br />
Ci-dessus, dans la classe <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Subject</span>, la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">changeName<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span> enverra un message <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #FF0000;">&quot;nameChanged&quot;</span></span> aux observateurs de l'instance.<br />
Après l'instanciation de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Subject</span>, la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">onNameChanged<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span> souscrit aux messages <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #FF0000;">&quot;nameChanged&quot;</span></span> du sujet.<br />
Par conséquent, lorsque <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">changeName<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span> est appelée, une popup d'alerte apparaît.<br />
<br />
Comme nous pouvons le voir, avec un tel <i>pattern</i>, aucun héritage via <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #0000ff;font-weight:bold">extends</span></span> ou <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #0000ff;font-weight:bold">implements</span></span> n'est requis. Juste une simple composition.<br />
<br />
<b><font size="2">Exemple avec des données complémentaires</font></b><br />
<br />
Nous pouvons envoyer des données complémentaires aux observateurs comme nous pouvons le voir ci-dessous :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">/// &lt;reference path=&quot;paon.d.ts&quot; /&gt;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">class</span> Subject <span style="color: black;">&#123;</span>
	<span style="color: #0000ff;font-weight:bold">private</span> name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
	observable<span style="color: black;">:</span> Paon.<span style="color: #0080ff;">Observable</span><span style="color: black;">;</span> <span style="color: #808080;">// Composant Observer Pattern</span>
&nbsp;
	<span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">observable</span> <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Paon.<span style="color: #0080ff;">Observable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// Instanciation / Initialisation</span>
	<span style="color: black;">&#125;</span>
&nbsp;
	changeName<span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#123;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">observable</span>.<span style="color: #0080ff;">notifyObservers</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;nameChanged&quot;</span><span style="color: black;">,</span> <span style="color: black;">&#123;</span> data<span style="color: black;">:</span> name <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// Un message avec une donn&eacute;e compl&eacute;mentaire est envoy&eacute; aux observateurs</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span><span style="color: black;">;</span>
	<span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">function</span> onNameChanged<span style="color: black;">&#40;</span>msg<span style="color: black;">:</span> <span style="color: black;">&#123;</span> data<span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
	alert<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Name has changed into &quot;</span> <span style="color: black;">+</span> msg.<span style="color: #0080ff;">data</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">let</span> subject <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Subject<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Penelope&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
subject.<span style="color: #0080ff;">observable</span>.<span style="color: #0080ff;">addObserver</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;nameChanged&quot;</span><span style="color: black;">,</span> onNameChanged<span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// La fonction onNameChanged() souscrit aux messages &quot;nameChanged&quot; du sujet</span>
&nbsp;
subject.<span style="color: #0080ff;">changeName</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Melissa&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: #808080;">// Une popup d'alerte appara&icirc;t: &quot;Name has changed into Melissa&quot;</span></pre></td></tr></table></pre>
</div><br />
Le paramètre <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">msg</span> dans la function <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">onNameChanged<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span> contient la donnée complémentaire que nous avons envoyé via la méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">changeName<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span>. Ici, c'est un objet avec la propriété <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">data</span>, mais ça pourrait être n'importe quoi.<br />
<br />
<b><font size="2">Importation de module</font></b><br />
<br />
Cette bibliothèque peut également être importée en tant que module avec l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #0000ff;">import</span></span> :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">import</span> Paon <span style="color: #0000ff;">from</span> <span style="color: #FF0000;">&quot;./paon&quot;</span><span style="color: black;">;</span> <span style="color: #808080;">// Emplacement du fichier de d&eacute;claration .d.ts</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">class</span> Subject <span style="color: black;">&#123;</span>
	<span style="color: #0000ff;font-weight:bold">private</span> name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
	observable<span style="color: black;">:</span> Paon.<span style="color: #0080ff;">Observable</span><span style="color: black;">;</span> <span style="color: #808080;">// Composant Observer Pattern</span>
&nbsp;
	<span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">observable</span> <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Paon.<span style="color: #0080ff;">Observable</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// Instanciation / Initialisation</span>
	<span style="color: black;">&#125;</span>
&nbsp;
	changeName<span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#123;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
		<span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">observable</span>.<span style="color: #0080ff;">notifyObservers</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;nameChanged&quot;</span><span style="color: black;">,</span> <span style="color: black;">&#123;</span> data<span style="color: black;">:</span> name <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// Un message avec une donn&eacute;e compl&eacute;mentaire est envoy&eacute; aux observateurs</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span><span style="color: black;">;</span>
	<span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">function</span> onNameChanged<span style="color: black;">&#40;</span>msg<span style="color: black;">:</span> <span style="color: black;">&#123;</span> data<span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
	alert<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Name has changed into &quot;</span> <span style="color: black;">+</span> msg.<span style="color: #0080ff;">data</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">let</span> subject <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Subject<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Penelope&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
subject.<span style="color: #0080ff;">observable</span>.<span style="color: #0080ff;">addObserver</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;nameChanged&quot;</span><span style="color: black;">,</span> onNameChanged<span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// La fonction onNameChanged() souscrit aux messages &quot;nameChanged&quot; du sujet</span>
&nbsp;
subject.<span style="color: #0080ff;">changeName</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Melissa&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: #808080;">// Une popup d'alerte appara&icirc;t: &quot;Name has changed into Melissa&quot;</span></pre></td></tr></table></pre>
</div><br />
Seule l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><span style="color: #0000ff;">import</span></span> remplace la référence des exemples précédents. A part cela, le reste du code est identique.<br />
<br />
<br />
<b><font size="3">Documentation de l'API</font></b><br />
<br />
Ajoute un observateur à un type de message (similaire à la fonction DOM <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">addEventListener<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span>) :<br />
<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Paon.<span style="color: #0080ff;">Observable</span>.<span style="color: #0080ff;">addObserver</span><span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">type</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">,</span> observer<span style="color: black;">:</span> Observer<span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span></span></div><br />
<br />
Retire un observateur d'un type de message (similaire à la fonction DOM <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">removeEventListener<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span>) :<br />
<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Paon.<span style="color: #0080ff;">Observable</span>.<span style="color: #0080ff;">removeObserver</span><span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">type</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">,</span> observer<span style="color: black;">:</span> Observer<span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span></span></div><br />
Retire tous les observateurs d'un type de message :<br />
<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Paon.<span style="color: #0080ff;">Observable</span>.<span style="color: #0080ff;">removeObserversType</span><span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">type</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span></span></div><br />
<br />
Envoie une message aux observateurs (similaire à la fonction DOM <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">dispatchEvent<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></span>) :<br />
<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Paon.<span style="color: #0080ff;">Observable</span>.<span style="color: #0080ff;">notifyObservers</span><span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">type</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">,</span> msg<span style="color: black;">?:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">void</span><span style="color: black;">;</span></span></div><br />
<br />
<b><font size="3">Contributeurs</font></b><br />
yahiko<br />
<br />
<br />
<b><font size="3">Licence</font></b><br />
MIT</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1616/paon-design-pattern-observateur-heritage-typescript-javascript/</guid>
		</item>
		<item>
			<title><![CDATA[Conseils généraux sur le processus de développement solo d'un jeu]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1608/conseils-generaux-processus-developpement-solo-d-jeu/</link>
			<pubDate>Thu, 01 Sep 2016 10:49:59 GMT</pubDate>
			<description>*Avant-Propos* 
 
Ce qui suit...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><b><font size="3">Avant-Propos</font></b><br />
<br />
<i>Ce qui suit est une traduction de mon cru qui était restée dans un fond de tiroir d'un article de Macoy Madson qui avait eu la gentillesse d'accorder son autorisation&nbsp;: <a href="http://www.gamedev.net/page/resources/_/business/production-and-management/general-tips-on-the-process-of-solo-game-development-r3281" target="_blank">General Tips on the Process of Solo Game Development</a></i><br />
<br />
<br />
<b><div style="text-align: center;"><font size="5">Conseils généraux sur le processus de développement solo d'un jeu</font></div></b><br />
<br />
En tant que développeur de jeu solo, il est important d'apprendre autant que possible sur tout ce que vous pouvez, y compris le processus que vous suivez en faisant des jeux. Le processus, je vais en parler comprend les étapes suivantes :<br />
<ul><li style="">l'Idée ;</li><li style="">le Prototype ;</li><li style="">l'Itération ;</li><li style="">le Test ;</li><li style="">la Finalisation.</li></ul><br />
<br />
J'espère vous fournir des conseils utiles sur chaque étape de ce processus de sorte que vous pourrez améliorer la vitesse de développement et la qualité de vos jeux.<br />
<br />
<br />
<b><font size="4">Le processus, étape par étape</font></b><br />
<br />
Tout d'abord, il est important de noter que ce n'est pas un processus en «&nbsp;cascade&nbsp;» linéaire. Il est très organique. Alors que vous commencez toujours avec une idée, les étapes suivantes de prototypage, d'itération, et de test se passeront de façon désordonnée. C'est une bonne chose, car il encourage l'expérimentation et va à l'encontre de la rigidité de la conception d'un jeu, et ce qui permet l'évolution positive de l'ensemble. Au fil du temps, vous aurez une meilleure idée sur la façon dont vous suivez habituellement ce processus et comment vous pouvez l'améliorer.<br />
<br />
<b><font size="3">Première étape : l'Idée</font></b><br />
<br />
Les développeurs de jeux débutants pensent parfois que c'est l'étape la plus importante dans le processus, et que tout développement doit être à l'arrêt tant qu'une idée n'est pas explorée à fond. Suite à cela, ils ont tendance à surconcevoir (eg. d'indigestes documents de game design), voir trop grand par rapport à leurs compétences, et à surestimer la valeur des idées. Cela fait également une conception beaucoup plus rigide, qui finit par affecter négativement le jeu sur le long terme.<br />
<br />
Bien que l'idée soit importante, il est plus important de comprendre la fragilité de vos connaissances tant que vous n'aurez pas fait un prototype et tester cette idée. Vous verrez que les idées qui sont dans votre tête peuvent paraître sympa, mais que jouer à un prototype de cette idée finit par être vraiment ennuyeux. Vous verrez également qu'une idée «&nbsp;terne&nbsp;» peut donner un prototype vraiment amusant&nbsp;!<br />
<br />
Au cours de cette étape, assurez-vous que votre objectif et vos contraintes soient bien définis. Par exemple, «&nbsp;faire un jeu fun&nbsp;» n'est pas un objectif très clair, tandis que «&nbsp;faire un jeu dans un mois qui utilise le thème du jeu Flowers et utilise de préférence le nouveau système COM&nbsp;» l'est. Le deuxième exemple montre également de bonnes contraintes. Certaines contraintes très immédiates qui s'appliquent à la plupart des gens qui font un jeu dans un certain laps de temps («&nbsp;avant la mort&nbsp;», même) et de rester à l'intérieur (voire très légèrement au-dessus) de votre gamme de compétences. Les contraintes peuvent vous aider à penser à d'autres idées, mais il est souvent bon de faire varier le niveau de degrés de liberté que vous avez sur chaque projet de jeu.<br />
<br />
L'inspiration est un mot qui revient souvent quand on parle des idées. N'oubliez pas que l'inspiration vient de partout, telle que de votre vie, d'autres médias, la théorie sur la conception de jeux, ou même la génération aléatoire&nbsp;! La chose la plus importante que vous devez savoir sur «&nbsp;l'inspiration&nbsp;» est de ne pas sauter sur la première idée venue&nbsp;! Lorsque vous êtes «&nbsp;inspiré&nbsp;», votre cerveau pompe ces substances chimiques associées à la récompense suite à cette production heureuse d'idée, ce qui vous rend très peu objectif sur les défauts de cette idée&nbsp;! Tout ce que vous avez à faire est de vous donner du temps. Peu importe à quel point l'idée vous semble bonne sur le coup, donnez-vous au moins trois ou quatre jours avant de faire davantage que d'y penser et d'écrire à son sujet.<br />
<br />
À un niveau inférieur, il est important de se concentrer sur la/les mécanique/s de votre idée. Rappelez-vous, vous écrivez un jeu, pas une histoire, donc vous avez besoin d'un gameplay&nbsp;! Si vous ne pouvez pas penser à bon gameplay pour cette histoire, peut-être que cette histoire serait mieux véhiculée sous une autre forme de média.<br />
<br />
Lorsque vous avez une idée et que vous avez patienté un laps de temps suffisant (et qu'elle sonne toujours bien), la prochaine chose que vous devez faire est de la réduire à sa plus simple expression. Cherchez ce qui vous fait vraiment aimer cette idée. Vous devez trouver le(s) élément(s) noyau(x) le(s) plus fondamenta(ux) qui font que cette idée est si attirante pour vous. C'est la première chose dont vous avez besoin pour faire le prototype puisque l'intégralité de votre jeu reposera sur ces éléments de base&nbsp;!<br />
<br />
Sur une note plus sombre, rappelez-vous que vous allez mourir. Gardez cela à l'esprit, et faites votre jeu comme si c'était le dernier.<br />
<br />
<b><font size="3">Deuxième étape : Prototype</font></b><br />
<br />
Si le chapitre Idée n'a pas été suffisamment explicite, je vais le répéter&nbsp;: vous ne pouvez pas voir le potentiel (positif ou négatif) d'une idée tant que vous ne l'avez pas prototypée&nbsp;! Heureusement, c'est souvent l'étape la plus amusante dans le développement d'un jeu parce vous voyez votre idée prendre vie. Cependant, il est aussi important de prototyper correctement afin d'exploiter le résultat le plus efficacement possible.<br />
<br />
Lorsque vous prototypez, vous devez être ouvert à l'échec. Si vous craignez un échec, vous ne pourrez jamais sortir ce jeu. J'aime bien conserver mes prototypes hors de mon dossier de sources vérifiés et sur le bureau Windows (ou équivalent), juste parce que cela met l'accent sur l'aspect ludique et temporaire que cette phase de prototypage a besoin pour réussir. Si vous vous plantez sur un prototype, c'est important de vous dire que c'était attendu et absolument normal&nbsp;!<br />
<br />
Du fait de cette tolérance à l'échec, vous devez également développer vos prototypes rapidement, parce que les chances sont que vous ferez l'expérience que l'échec de nombreuses fois avant de créer un prototype gagnant. Un gain important de vitesse peut être obtenu par l'optimisation de votre code. Je ne veux pas dire l'optimisation de sa performance, mais l'optimisation de son usage. Vous souhaitez concevoir votre code pour une réutilisation et une simplicité maximale, ce qui implique la création d'une bibliothèque complète de codes réutilisables et pertinents, et de faire un modèle de jeu que vous pouvez copier et réutiliser. Ce modèle de jeu devrait inclure une fenêtre ouverte avec l'affichage d'un sprite, la gestion des entrées et un makefile de travail, etc. Recherchez le confort&nbsp;!<br />
<br />
En outre, vous devriez éviter d'utiliser des outils soi-disant «&nbsp;plus faciles&nbsp;» pour le prototypage, mais plutôt tenez-vous-en à ce que vous savez et ce avec quoi vous avez le plus d'expérience, parce que cela donnera le plus rapide des prototypes (et le plus utile). J'écris la plupart de mes prototypes en C++ parce que j'ai quatre ans d'expérience avec ce langage et sa bibliothèque.<br />
<br />
Avant de rédiger la moindre ligne de code, assurez-vous que vous avez une question bien définie à laquelle vous souhaitez que votre prototype réponde. Cette question devrait être très simple et devrait impliquer en priorité les parties les plus importantes et/ou «&nbsp;à risque&nbsp;» de votre idée de jeu. Idéalement, vous devriez écrire la question quelque part clairement et de façon visible et ainsi vous ne devriez pas faire de hors-piste. Dès que le prototype répond à cette question et débroussaille un peu le terrain, vous devriez passer à un autre.<br />
<br />
Une fois que vous avez fait le(s) prototype(s) qui démontre la puissance de votre idée, trouvez l'élément de base qui le démontre et laissez de côté tout le reste. La simplicité est la clé d'une conception élégante&nbsp;!<br />
<br />
<b><font size="3">Troisième étape : Itération</font></b><br />
<br />
À ce stade, vous avez fait suffisamment de prototypes pour démontrer le potentiel positif de votre idée. Vous avez également démontré la faisabilité technique de l'idée et la façon dont vous pourriez aborder sa mise en œuvre dans le code de production. Vous avez aussi cerné ce que vous aimez le plus de cette l'idée et avez retiré ce qui n'était pas nécessaire à l'expérience du joueur. Si vous n'avez pas tout cela, revenez en arrière et faites plus de prototypes&nbsp;!<br />
<br />
Quand je dis ici itération, je veux parler du développement et de l'amélioration du produit final. Vous devriez éviter d'utiliser un prototype pour votre code de production parce que ce prototype était du sur-mesure pour répondre à une question donnée, et pas pour devenir un jeu complet. À ce stade du développement, vous utilisez vos pratiques de codage les plus pérennes pour construire la version finale du jeu. Il y a beaucoup d'articles qui traitent de ces pratiques, c'est donc désormais le moment d'utiliser ce que vous avez appris sur le codage de haute qualité. Le prototypage n'était pas le moment d'utiliser ces pratiques, car les prototypes vont être jetés de toute façon&nbsp;!<br />
<br />
Les itérations doivent passer en revue les éléments du plus important au moins important (tout comme les prototypes). Si vous codez un menu principal ou des fantaisies graphiques avant que vous n'ayez votre mécanique principale d'opérationnel, vous faites quelque chose de très, très mal&nbsp;! Personne ne se soucie de vos détails graphiques ou de vos menus, ils se soucient du gameplay&nbsp;! Faites le «&nbsp;jouet&nbsp;» d'abord, et gardez les menus et le fignolage pour la fin.<br />
<br />
Bien que vous travailliez maintenant sur le code «&nbsp;final&nbsp;», vous devriez toujours continuer à expérimenter. Soyez très prudent avec de telles expériences, car elles peuvent vous faire perdre votre vision de cet élément de base sur lequel vous vous concentriez avant. Assurez-vous que vous savez pourquoi votre jeu est intéressant. Neuf fois sur dix, ce n'est pas parce que vous avez une physique réaliste pour un PNJ ou que vous pouvez extraire les métaux sous terre&nbsp;! Vos expériences devraient être séparées de la production (si vous utilisez un gestionnaire de code source, c'est là où la «&nbsp;ramification&nbsp;» devient utile) et facilement annulables. Vous devriez vous concentrer sur de telles expériences pour l'amélioration de l'élément de base uniquement&nbsp;! Si l'expérience est trop divergente de l'élément de base, vous devriez la spécifier et la prototyper plus tard.<br />
<br />
Ne jamais, en aucune circonstance, optimiser prématurément&nbsp;! En tant que programmeur, vous avez probablement entendu parler de KISS, qui signifie «&nbsp;Keep It Simple, Stupid&nbsp;!&nbsp;» (NdT&nbsp;: Restez simple et stupide). Suivez ce principe autant que vous le pouvez&nbsp;! Jonathan Blow parle d'algorithmes et de structures de données et comment elles sont optimisées pour des performances ou la mémoire, mais ne sont pas «&nbsp;optimisées pour l'usage&nbsp;». Il est plus important de finir un jeu dans un mois qui tourne à 20 FPS que de finir dans un an pour 60 FPS&nbsp;!<br />
<br />
Concernant le codage pendant le cycle itératif, vous souhaitez identifier des composants qui peuvent facilement être réutilisés dans de futurs jeux et les ajouter à votre bibliothèque plutôt que de les rendre spécifiques à votre jeu. Cela permettra non seulement d'améliorer votre bibliothèque, mais aussi de rendre chaque jeu suivant (et prototypes) plus rapide à développer. N'essayez pas de réutiliser des composants qui sont trop spécifiques cependant&nbsp;!<br />
<br />
Pendant que vous enrichissez par itération votre bibliothèque de composants, concentrez-vous sur les fonctionnalités qui a) sont utiles non pour leur performance, mais pour ce qu'elles accomplissent et b) d'encourager la réutilisation du code et ainsi raccourcir les temps de développement. Par exemple, la détection et la résolution des collisions sont extrêmement utiles et cela vaut la peine de prendre son temps à les implémenter, mais la mise en œuvre d'une routine de collision «&nbsp;optimisée&nbsp;» n'en vaut pas la peine. Rappelez-vous, ne faites pas quelque chose, sauf si vous en avez besoin&nbsp;! Comme exemple de fonctionnalités (b), j'ai récemment mis en œuvre mon propre système COM (ou CES) parce que j'ai vu combien la réutilisation du code devenait plus facile avec elle. Bien sûr, cela impacte négativement les performances, mais l'idée de composants dynamiques, portables et réutilisables compense cet impact par l'optimisation de l'usage&nbsp;!<br />
<br />
Si vous en êtes à ce point, il n'y a aucune raison d'abandonner le projet&nbsp;! Bien sûr, vous avez beaucoup appris de vos erreurs de codage et un recodage complet rendrait probablement le projet meilleur, mais ne perdez pas votre temps&nbsp;! Beaucoup de développeurs débutants de jeux abandonnent sans cesse des projets en plein milieu du développement. C'est la principale raison pour laquelle ils sont encore des développeurs débutants&nbsp;! Vous avez touché ce qui est communément connu comme «&nbsp;le Mur&nbsp;», le point où vous ne voulez plus continuer le développement d'un projet. Il suffit de l'abattre et de persister, sinon tout le travail que vous avez réalisé ne vaudra plus rien (pour les joueurs, au moins)&nbsp;! J'ai publié sept jeux, et deux d'entre eux se sont avérés être un enfer vers la fin. J'ai persisté, et j'ai appris de mes erreurs. Vous devez terminer complètement vos projets&nbsp;! N'abandonnez pas&nbsp;!<br />
<br />
Cette étape de l'itération sera fortement influencée par l'étape suivante, qui est...<br />
<br />
<b><font size="3">Quatrième étape : Tests</font></b><br />
<br />
Je dois admettre, j'ai beaucoup de mal avec les tests. Il est assez difficile de les faire correctement, mais lorsque c'est fait correctement, cela aboutit à améliorer votre jeu considérablement. La phase de tests est assez simple, donc je vais vous présenter quelques règles de base que vous pourrez utiliser pour les faire plus efficacement.<br />
<br />
Tout d'abord, testez tôt, testez souvent&nbsp;! Vous ne pouvez jamais trop tester&nbsp;! Testez dès le stade du prototypage, et pas plus tard que la publication. Vous verrez que certaines parties de votre jeu qui sont parfaitement claires pour vous seront complètement confuses pour d'autres, par conséquent, ne développez pas dans le vide&nbsp;!<br />
<br />
Ensuite, diversifiez&nbsp;! Cela inclut les personnes et la technologie. Exécuter votre jeu sur autant d'appareils et de systèmes d'exploitation que vous le pouvez. Un de mes jeux fonctionnait bien sur mes deux ordinateurs (avec des configurations très différentes) et des systèmes d'exploitation virtuels, mais avait des bogues de déplacement qui ruinaient mon jeu sur la plupart des autres ordinateurs&nbsp;! Quand il s'agit de personnes, n'écartez aucune catégorie de gens. Laissez quiconque jouer à votre jeu, peu importe son sexe, son âge, ou ses centres d'intérêt&nbsp;! Plus vos testeurs seront divers, plus votre public sera divers, et moins votre jeu sera subjectif.<br />
<br />
Ne gaspillez pas vos testeurs. Après un certain temps, ils deviendront très partiaux, notamment parce qu'ils auront vu les versions précédentes du jeu. Il est préférable que vos testeurs n'aient aucun préjugé et un esprit ouvert, alors assurez-vous de changer les gens souvent.<br />
<br />
L'observation est la chose la plus importante que vous devez apprendre à faire lors d'une session de tests. Regardez quand les gens parlent, quand les gens arrêtent de parler, quand leur personnage meurt, quand ils réussissent, et quand ils arrêtent de jouer. Les probabilités sont que la plupart des gens vont faire la même chose, malgré l'influence de votre simple présence. L'observation est aussi la seule chose que vous devez faire pendant une session de tests. Ne leur indiquez pas le contexte, ou expliquer quelque chose, ou les aider, ou quoi que ce soit. Il suffit de regarder et de prendre des notes.<br />
<br />
Après qu'ils ont fini de jouer, vous devriez leur poser les trois questions suivantes :<br />
<ul><li style="">Qu'avez-vous aimé&nbsp;?</li><li style="">Qu'est-ce que vous détestez&nbsp;?</li><li style="">Qu'est-ce qui vous a dérouté&nbsp;?</li></ul><br />
<br />
Cela vous donnera des retours très précis sur ce dont vous avez besoin de mettre l'accent et ce que vous devez changer. Aussi, lorsque le joueur vous fait des suggestions pour améliorer le jeu, ne vous focalisez pas sur la suggestion, mais sur les causes qui ont fait qu'il vous a fait cette suggestion.<br />
<br />
<b><font size="3">Cinquième étape : Finalisation&nbsp;!</font></b><br />
<br />
Si vous en êtes rendu à ce point, vous êtes prêt à terminer votre jeu&nbsp;! Les derniers 10&nbsp;% de développement ressemblent souvent à 90&nbsp;%, mais il ne faut pas abandonner&nbsp;! N'oubliez pas que même un jeu à «&nbsp;90&nbsp;% terminé&nbsp;» est un jeu qui ne vaut rien&nbsp;! La finition c'est avant tout vous pousser à travers le Mur et faire en sorte que tous ces bouts épars soient rattachés entre eux. Rappelez-vous jusqu'où vous êtes parvenu, et regardez la distance qu'il vous reste à parcourir. Ce n'est pas si loin que ça&nbsp;!<br />
<br />
Pendant que vous apportez la touche finale et packagez le tout pour la première fois, testez sur autant de plateformes que possible. Vous devez tout tester, même vos fichiers «&nbsp;lisez-moi&nbsp;» (une fois mon caractère de nouvelle ligne était de type Unix et cela ne fonctionnait pas sur les ordinateurs Windows&nbsp;:) )&nbsp;!<br />
<br />
Il est recommandé que le cheminement qu'un joueur emprunte pour découvrir votre jeu et pour ensuite y jouer soit le plus court et le plus direct possible. Abaissez toutes les barrières que vous pouvez, et faites en sorte que votre jeu soit facile à juger. La praticité est essentielle à ce stade.<br />
<br />
Si vous vous demandez pourquoi votre jeu ressemble toujours à un projet «&nbsp;amateur&nbsp;», c'est parce qu'il n'est pas assez fignolé. De très petites choses, comme les menus ou les écrans de chargement, peuvent faire une grande différence sur les impressions du joueur envers votre jeu. Rappelez-vous, la première chose que le joueur verra sera l'une de ces choses, il est donc très important de bien les faire. Étudiez les jeux «&nbsp;professionnels&nbsp;» et les raisons pour lesquelles ils ont l'air plus «&nbsp;professionnels&nbsp;». Le fignolage est en grande partie une question de feeling, ce qui fait qu'il est juste nécessaire de pratiquer pour y arriver, mais le temps supplémentaire en vaut la peine.<br />
<br />
Si vous êtes extrêmement gêné par la «&nbsp;qualité&nbsp;» de votre jeu ou si vous savez qu'elle a de sérieuses lacunes, corrigez autant que vous le pouvez et publiez-le quand même. Terminez votre projet, apprenez de vos erreurs et faites mieux pour le prochain jeu.<br />
<br />
<br />
<b><font size="4">Conclusion</font></b><br />
<br />
Vous venez de faire un jeu&nbsp;! Félicitations&nbsp;! Maintenant, faites-en à nouveau, évitez seulement les erreurs qui ont causé du tort à la qualité de votre dernier jeu.<br />
<br />
J'ai couvert beaucoup d'aspects, donc je vais juste faire un bref rappel de chaque étape&nbsp;:<br />
<br />
<b>Idée</b><br />
<ul><li style="">le prototypage reste essentiel ;</li><li style="">fixez-vous un objectif et des contraintes bien définies ;</li><li style="">donnez-vous un peu de temps ;</li><li style="">trouvez l'élément central sur lequel repose votre idée ;</li><li style="">vous allez mourir, alors faites en sorte qu'elle ait de l'importance&nbsp;!</li></ul><br />
<b>Prototypage</b><br />
<ul><li style="">soyez ouvert à l'échec ;</li><li style="">faites-le aussi rapidement que possible, et rendez votre code le plus pratique possible ;</li><li style="">utilisez les outils que vous connaissez déjà ;</li><li style="">ayez une question bien définie à résoudre.</li></ul><br />
<b>Itération</b><br />
<ul><li style="">faites du code de haute qualité ;</li><li style="">allez des éléments les plus importants aux moins importants ;</li><li style="">expérimentez, mais ne perdez pas de vue l'élément de base ;</li><li style="">KISS / Optimisez l'usage / PAS d’optimisation prématurée ;</li><li style="">ajoutez le code réutilisable à votre bibliothèque ;</li><li style="">n'ajoutez que les fonctionnalités à votre bibliothèque qui rendent le développement plus rapide ou qui ajoutent des possibilités (ne codez pas quelque chose pour améliorer la vitesse, sauf si vous en avez besoin) ;</li><li style="">ne pas abandonner ou renoncer à un projet à ce niveau&nbsp;!</li></ul><br />
<b>Tests</b><br />
<ul><li style="">testez tôt, testez souvent ;</li><li style="">diversifiez les origines de vos testeurs ;</li><li style="">remplacez vos testeurs trop utilisés ;</li><li style="">posez des questions.</li></ul><br />
<b>Finalisation</b><br />
<ul><li style="">persistez ;</li><li style="">testez, testez, testez&nbsp;!</li><li style="">rendez facile la découverte de votre jeu</li><li style="">fignolez ;</li><li style="">publiez-le et apprenez de vos erreurs</li></ul><br />
<br />
Merci d'avoir pris le temps de lire ça&nbsp;! J'espère que je vous ai aidé&nbsp;!</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1608/conseils-generaux-processus-developpement-solo-d-jeu/</guid>
		</item>
		<item>
			<title>Clash of the Daemons</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1603/clash-of-the-daemons/</link>
			<pubDate>Tue, 30 Aug 2016 08:47:31 GMT</pubDate>
			<description>Image :...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><a href="http://yahiko.developpez.com/apps/ClashDaemons/" target="_blank"><img src="http://www.developpez.net/forums/attachments/p218977d1472388444/applications/developpement-2d-3d-jeux/projets/we-jv6-clash-of-the-daemons/screenshot20160828c.png/" border="0" alt="" /></a></div><br />
Dans le prolongement d'un projet débuté au début du mois d'août sur l'implémentation d'un système d'IA, j'ai réalisé pour le Week-End JV de DVP un petit jeu (ou plutôt une petite démo) dans le style hack 'n slash mettant en oeuvre quelques comportements (<i>behaviors</i>).<br />
<br />
<b>Lien</b> : <a href="http://yahiko.developpez.com/apps/ClashDaemons/" target="_blank">http://yahiko.developpez.com/apps/ClashDaemons/</a><br />
<br />
<b>Contrôles</b> :<br />
<ul><li style="">Flêches pour se déplacer</li><li style="">CTRL pour attaquer au corps-à-corps</li><li style="">MAJ pour attaquer à distance</li></ul><br />
<br />
Les sprites des monstres viennent de OpenGameArt.org. L'écran-titre et le HUD ont été réalisé par mes soins.<br />
<br />
<br />
<b>Fonctionnalités</b> implémentées :<br />
<ul><li style="">Collisions 2D à base de cercles</li><li style="">IA (voir plus bas)</li><li style="">Pathfinding (not enabled for now)</li><li style="">Respawn des monstres</li></ul><br />
<br />
<br />
<b>Comportements</b> d'IA implémentés :<br />
<img src="http://www.developpez.net/forums/attachments/p218897d1472277558/applications/developpement-2d-3d-jeux/projets/we-jv6-clash-of-the-daemons/demonsample.png/" border="0" alt="" /> : Attaque au corps-à-corps<br />
<br />
<img src="http://www.developpez.net/forums/attachments/p218997d1472399303/applications/developpement-2d-3d-jeux/projets/we-jv6-clash-of-the-daemons/demonsampleorange.png/" border="0" alt="" /> : Attaque à distance<br />
<br />
<img src="http://www.developpez.net/forums/attachments/p218996d1472399302/applications/developpement-2d-3d-jeux/projets/we-jv6-clash-of-the-daemons/demonsamplekhaki.png/" border="0" alt="" /> : Hit and run<br />
<br />
<img src="http://www.developpez.net/forums/attachments/p218998d1472399304/applications/developpement-2d-3d-jeux/projets/we-jv6-clash-of-the-daemons/demonsampleyellow.png/" border="0" alt="" /> : Simple vagabondage<br />
<br />
<br />
<b>Technologies</b> :<br />
<ul><li style="">Ecrit en TypeScript</li><li style="">Soutenu par le framework Phaser</li></ul><br />
<br />
<br />
Principales <b>métriques</b> de ce projet :<br />
<ul><li style="">3219 lignes de code rédigées (hors framework, commentaires et lignes blanches)</li><li style="">148 ko d'assets graphiques</li></ul><br />
<br />
<div style="text-align: center;"><img src="http://www.html5gamedevs.com/uploads/monthly_2016_08/screenshot20160829.gif.e4feb9b2a7048d9b25f658d52467b276.gif" border="0" alt="" /></div></blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1603/clash-of-the-daemons/</guid>
		</item>
		<item>
			<title>Geometry2D : Une bibliothèque TypeScript pour la géométrie 2D</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1572/geometry2d-bibliotheque-typescript-geometrie-2d/</link>
			<pubDate>Sun, 14 Aug 2016 10:27:02 GMT</pubDate>
			<description>Image :...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="http://www.developpez.net/forums/attachments/p156011d1410504996/webmasters-developpement-web-9/javascript-ajax-typescript-dart-2000/typescript-2001/typescript-annonce-nouveau-compilateur/logo-typescript.png/" border="0" alt="" /></div><br />
Dans le cadre d'un projet de jeu vidéo, j'ai été amené à réaliser un prototype en TypeScript avec le framework Phaser. J'en profite pour partager une petite collection de fonctions que j'ai regroupé dans une bibliothèque que j'ai très simplement nommé <b>Geometry2D</b>.<br />
<br />
Les fonctions qu'on y trouve pourront être utiles à celles et ceux qui manipulent des vecteurs 2D, des angles, des rectangles et des cercles dans leur projet. On pourra y trouver également des fonctions pour la détection du recouvrement, utile lors de la détection de collision en particulier.<br />
<br />
D'un point de vue de la conception, j'ai pris le parti de rester sur un mode fonctionnel. C'est-à-dire qu'il n'y a pas de classes, seulement des interfaces qui pourront être instanciés sous la forme de simples objets par exemple.<br />
<br />
Je compte maintenir cette bibliothèque et l'enrichir progressivement. N'hésitez pas à me faire part de vos suggestions.<br />
<br />
A noter que pour le moment la documentation reste très succincte, pour ne pas dire inexistante :aie:, mais ça devrait s'améliorer avec le temps. Rassurez-vous, le fichier source <b><i>geometry2D.ts</i></b> est relativement basique et simple à comprendre de lui-même.<br />
<br />
Le code source est disponible sur <u><a href="https://github.com/yahiko00/Geometry2D" target="_blank">mon dépôt GitHub</a></u> sous licence MIT.<br />
<br />
En espérant que cela pourra vous être utile,<br />
<br />
Bon développement !</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1572/geometry2d-bibliotheque-typescript-geometrie-2d/</guid>
		</item>
		<item>
			<title><![CDATA[Les bases de l'asynchrone en JavaScript]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1546/bases-l-asynchrone-javascript/</link>
			<pubDate>Mon, 01 Aug 2016 07:00:00 GMT</pubDate>
			<description>Pièce jointe 216963...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p216963d1470076303/c-cpp/outils-c-cpp/visual-cpp/mfc/mfc-ado-connection/1024.png/" border="0" alt="Nom : 1024.png
Affichages : 42836
Taille : 17,1 Ko"  style="float: CONFIG" /></div><br />
JavaScript bien qu'omniprésent de nos jours reste un langage très décrié à cause notamment de nombreuses approximations dans les spécifications de sa syntaxe. Mais il serait simpliste et erroné de croire que le succès de ce langage n'est dû qu'à un phénomène de mode (cela fait une vingtaine d'années que cela dure), ou que ses partisans sont de mauvais développeurs répandant de mauvaises pratiques de programmation.<br />
<br />
Car au-delà des concepts phares comme l'héritage par prototype qui est à mon goût survendu, la véritable force du langage ne réside pas vraiment en lui, mais autour. Cette force, c'est son fonctionnement asynchrone dont les fondements ne sont pas toujours bien compris.<br />
<br />
<br />
<font size="4"><b>JavaScript : monothread et asynchrone</b></font><br />
<br />
JavaScript est un langage qui a été pensé pour évoluer dans un environnement monothread et asynchrone.<br />
<br />
Le terme thread pourrait être traduit en première approximation par processus. Le fait que le moteur JavaScript (grosso modo l'interpréteur JavaScript) soit monothread signifie que le moteur ne peut interpréter qu'une seule et unique instruction à la fois, via sa seule et unique pile d'exécution (<b>Call Stack</b>). Le principal avantage de ceci étant la simplicité.<br />
<br />
Le terme asynchrone fait référence au comportement de certains traitements dans JavaScript qui peuvent être délégués en dehors du moteur. Dans le cas d'une page Web, les traitements asynchrones seront délégués au navigateur. À noter que bien que le moteur JavaScript soit monothread, l'hôte (eg. le navigateur ou NodeJS) peut lui être multithreads. Les threads pouvant être l'application JavaScript en cours, le rendu de l'interface utilisateur (UI), la gestion des entrées/sorties (IO), etc.<br />
<br />
Sans cette possibilité de réaliser des appels asynchrones, une application JavaScript serait condamnée à bloquer le navigateur le temps de son exécution.<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p216635d1469714467/c-cpp/outils-c-cpp/visual-cpp/mfc/mfc-ado-connection/jsblocking.png/" border="0" alt="Nom : jsblocking.png
Affichages : 35827
Taille : 10,4 Ko"  style="float: CONFIG" /><br />
<i>Notification de blocage de Firefox par un script</i></div><br />
<br />
<font size="4"><b>Circuit de l'asynchrone</b></font><br />
<br />
L'asynchrone en JavaScript repose sur un circuit partant de la pile d'exécution, sortant du moteur JavaScript via les API du système hôte (<b>Host APIs</b>) qui peut être le navigateur ou NodeJS, la file d'attente des callbacks (<b>Callback Queue</b>), la boucle des événements (<b>Event Loop</b>), pour enfin revenir au moteur JavaScript sur la pile d'exécution.<br />
<br />
Il est important de noter que le seul composant du moteur JavaScript directement impliqué dans le circuit de l'asynchrone est la pile d'exécution. Les autres composants que sont les API du système hôte, la file d'attente des callbacks et la boucle des événements ne font pas à proprement parler partie de ce moteur JavaScript.<br />
<br />
Il est ainsi possible de dire que JavaScript est un peu plus qu'un langage, c'est aussi une architecture.<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p216661d1469721874/c-cpp/outils-c-cpp/visual-cpp/mfc/mfc-ado-connection/circuitasynchrone_empty.png/" border="0" alt="Nom : circuitasynchrone_empty.png
Affichages : 36451
Taille : 24,2 Ko"  style="float: CONFIG" /><br />
<i>Composants du circuit de l'asynchrone</i></div><br />
<font size="3"><b>Pile d'exécution</b></font><br />
<br />
Un programme comporte généralement des fonctions appelant d'autres fonctions (ou s'appelant elles-mêmes). Le rôle de la pile d'exécution est d'assurer le suivi de la chaîne d'appel en mémorisant la fonction et son contexte d'exécution (variables locales et paramètres d'appel). Un appel d'une fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">A()</span> dans le contexte global empilera un premier niveau sur la pile d'exécution. Si cette fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">A()</span> appelle en son sein une fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">B()</span>, alors un second niveau sera empilé sur la pile. Et si cette fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">B()</span> appelle une fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">C()</span>, alors un troisième niveau sera empilé sur la pile. Un niveau de la pile n'est retiré que lorsque la fonction appelée a terminé son exécution. C'est pourquoi lors d'appels récursifs mal implémentés, il est possible de dépasser la capacité de la pile et obtenir le fameux message d'erreur « <i>stack overflow</i> ».<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">function</span> <span style="color: #0080ff;">A</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #808080;">// Etat 1</span>
    <span style="color: #0080ff;">B</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
    <span style="color: #808080;">// Etat 5</span>
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #0000ff;">function</span> <span style="color: #0080ff;">B</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #808080;">// Etat 2</span>
    <span style="color: #0080ff;">C</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
    <span style="color: #808080;">// Etat 4</span>
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #0000ff;">function</span> <span style="color: #0080ff;">C</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #808080;">// Etat 3</span>
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #808080;">// Etat 0</span>
<span style="color: #0080ff;">A</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span style="color: #808080;">// Etat 6</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Appels imbriqués de fonctions</i><br />
<br />
<img src="https://www.developpez.net/forums/attachments/p216667d1469724265/c-cpp/outils-c-cpp/visual-cpp/mfc/mfc-ado-connection/piledexecution.png/" border="0" alt="Nom : piledexecution.png
Affichages : 36017
Taille : 15,9 Ko"  style="float: CONFIG" /><br />
<br />
<i>États successifs de la pile d'exécution lors d'appels imbriqués</i></div><br />
<font size="3"><b>APIs du système hôte</b></font><br />
<br />
Le système hôte (eg. navigateur, NodeJS) fournit toute une panoplie de fonctions et d'objets (API) au moteur JavaScript pour interagir avec lui ou avec le système d'exploitation. Certaines de ces fonctions sont asynchrones comme <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">XMLHttpRequest.send()</span>, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">FileReader.readFile()</span> dans le domaine des accès aux ressources ou encore le <i>listener</i> du DOM pour ce qui est de la gestion des événements, asynchrones par essence.<br />
<br />
Le programme principal JavaScript doit avoir la possibilité de savoir si un traitement asynchrone qu'il a appelé est terminé puis d'exploiter le résultat de ce traitement asynchrone en conséquence. C'est là qu'interviennent les fonctions callbacks. Il est courant en JavaScript que les callbacks soient des fonctions anonymes passées en paramètre et définies au moment même de l'appel de la fonction asynchrone.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">var</span> req = <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">XMLHttpRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
req.<span style="color: #0080ff;">open</span><span class="br0">&#40;</span><span style="color: #FF0000;">'GET'</span>, <span style="color: #FF0000;">'http://www.mozilla.org/'</span>, <span style="color: #339933;">true</span><span class="br0">&#41;</span>;
req.onreadystatechange = <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">callback</span><span class="br0">&#40;</span>aEvt<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span style="color: #808080;">// fonction callback</span>
  <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>req.readyState == <span style="color: #cc66cc;">4</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
     <span style="color: #0000ff;">if</span><span class="br0">&#40;</span>req.<span style="color: #0080ff;">status</span> == <span style="color: #cc66cc;">200</span><span class="br0">&#41;</span>
      <span style="color: #0080ff;">dump</span><span class="br0">&#40;</span>req.responseText<span class="br0">&#41;</span>;
     <span style="color: #0000ff;">else</span>
      <span style="color: #0080ff;">dump</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Erreur pendant le chargement de la page.<span style="color: #800000;">\n</span>&quot;</span><span class="br0">&#41;</span>;
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span>;
req.<span style="color: #0080ff;">send</span><span class="br0">&#40;</span><span style="color: #339933;">null</span><span class="br0">&#41;</span>; <span style="color: #808080;">// traitement asynchrone</span></pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Requête HTTP asynchrone au format XML sous un navigateur</i></div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:108px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">var</span> fs = <span style="color: #0080ff;">require</span><span class="br0">&#40;</span><span style="color: #FF0000;">'fs'</span><span class="br0">&#41;</span>;
&nbsp;
<span style="color: #808080;">// traitement asynchrone</span>
fs.<span style="color: #0080ff;">readFile</span><span class="br0">&#40;</span><span style="color: #FF0000;">'DATA'</span>, <span style="color: #FF0000;">'utf8'</span>, <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">callback</span><span class="br0">&#40;</span>err, contents<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span style="color: #808080;">// fonction callback</span>
    console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span>contents<span class="br0">&#41;</span>;
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><div style="text-align: center;"><i>Lecture asynchrone d'un fichier sous NodeJS</i></div><br />
<font size="3"><b>File d'attente des événements</b></font><br />
<br />
Une fois que le traitement asynchrone est terminé ou qu'un événement particulier survient, la callback qui a été fournie en paramètre est insérée dans la file d'attente des callbacks avant d'être prise en compte par la boucle des événements.<br />
<br />
<font size="3"><b>Boucle des événements</b></font><br />
<br />
La boucle des événements a pour but de surveiller l'état de la pile d'exécution. Si cette dernière est vide d'instruction à exécuter, la boucle des événements déplacera la callback en attente dans la file vers la pile d'exécution, permettant à cette callback d'être ainsi exécutée.<br />
<br />
<br />
<font size="4"><b>Déroulement</b></font><br />
<br />
Pour mieux illustrer l'implication des différents composants dans un appel asynchrone, nous allons nous définir une fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> qui appellera la fonction asynchrone standard <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span>.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">var</span> k = <span style="color: #cc66cc;">0</span>;
&nbsp;
<span style="color: #808080;">// D&eacute;finition de la fonction getData()</span>
&nbsp;
<span style="color: #0000ff;">function</span> <span style="color: #0080ff;">getData</span><span class="br0">&#40;</span>callback<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span><span style="color: #FF0000;">'getData()'</span><span class="br0">&#41;</span>;
&nbsp;
    <span style="color: #0080ff;">setTimeout</span><span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span style="color: #0080ff;">setTimeoutCB</span><span class="br0">&#40;</span>counter<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span style="color: #808080;">// callback asynchrone</span>
        console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span><span style="color: #FF0000;">'setTimeoutCB()'</span><span class="br0">&#41;</span>;
        <span style="color: #0080ff;">callback</span><span class="br0">&#40;</span><span style="color: #339933;">null</span>, counter<span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>, <span style="color: #cc66cc;">500</span>, ++k<span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #808080;">// Appel de la fonction getData()</span>
&nbsp;
<span style="color: #0080ff;">getData</span><span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span style="color: #0080ff;">getDataCB</span><span class="br0">&#40;</span>error, data<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span style="color: #808080;">// callback synchrone</span>
    console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span><span style="color: #FF0000;">'getDataCB()'</span><span class="br0">&#41;</span>;
&nbsp;
    console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span><span style="color: #FF0000;">'data: '</span>, data<span class="br0">&#41;</span>;
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
On peut constater dans le code ci-dessus, que la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span> appelée à l'intérieur de la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> appelle une fonction callback que nous avons nommée <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span> pour la clarté du propos, mais qui aurait très bien pu être anonyme.<br />
<br />
Cette fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span> a ici pour tâche d'appeler la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">callback()</span> qui est un paramètre de la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span>. C'est une des caractéristiques des fonctions callbacks.<br />
<br />
Lors de l'appel de la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span>, une fonction callback <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getDataCB()</span> lui est fournie en paramètre.<br />
<br />
Regardons ce qu'il se passe lors de cet appel.<br />
<br />
<div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p216799d1469822761/c-cpp/outils-c-cpp/visual-cpp/mfc/mfc-ado-connection/circuitasynchrone.png/" border="0" alt="Nom : circuitasynchrone.png
Affichages : 37109
Taille : 35,5 Ko"  style="float: CONFIG" /></div><br />
<b>(1)</b> Après que les fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> puis <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span> ont été empilées sur la pile d'exécution, la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span> qui fait partie de l'API du navigateur, est appelée et est prise en charge par celui-ci de façon asynchrone. À noter que cet appel à la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span> est la dernière instruction directement exécutée par le programme principal qui arrive ici à son terme. À ce moment, la pile d'exécution est vide.<br />
<br />
<b>(2)</b> Le décompte du délai s'effectue dans un thread à part, et lorsque le délai est épuisé, la fonction callback qui a été passée en paramètre de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span>, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span>, est envoyée vers la file d'attente. Notons que les paramètres de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span> sont fournis par <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span>. Ici, il s'agit juste d'un compteur numérique valant 1, mais avec d'autres fonctions asynchrones, ce pourrait être un message d'erreur ou des données binaires. L'important est d'avoir à l'esprit que les paramètres de la fonction callback sont fournis par la fonction asynchrone appelante.<br />
<br />
<b>(3)</b> La boucle des événements détecte la présence d'une callback, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span>, dans la file d'attente, et s'assure que la pile d'exécution est bien vide. Si c'est le cas, la boucle des événements envoie la callback sur la pile d'exécution où elle est exécutée.<br />
<br />
Suite à cela, ce qui n'est pas schématisé, c'est l'empilement par dessus <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span>, de la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">callback()</span> qui est le paramètre de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getData()</span> faisant référence à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">getDataCB()</span>. Le fait que <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span> ait toujours accès au paramètre <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">callback</span> vient de la propriété des fermetures en JavaScript (cf. <a href="http://www.developpez.net/forums/blogs/676693-yahiko/b174/js-principales-proprietes-fermetures/" target="_blank"><u>article</u></a>). La fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeoutCB()</span> n'étant pas elle une fonction asynchrone, contrairement à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">setTimeout()</span>, il n'y a pas d'appel à l'API du navigateur, pas de passage par la file d'attente et pas d'intervention de la boucle des événements pour exécuter la fonction. Il s'agit là de traitements synchrones qui restent donc sous l'entière responsabilité du moteur JavaScript.<br />
<br />
<i>Remarque : N'hésitez pas à relire plusieurs fois le code, le schéma et les explications pour bien visualiser le déroulement.</i><br />
<br />
<br />
<font size="4"><b>Conclusion</b></font><br />
<br />
Les mécanismes de l'asynchrone en JavaScript ne sont pas très compliqués à comprendre, mais non triviaux à expliquer comme on vient de le voir. Il n'existe finalement pas énormément de ressources à ce sujet sur le Web. J'espère tout de même que ce bref exposé vous aura aidé à mieux comprendre ce qui se déroule « sous le capot » lorsque vous utiliserez des fonctions asynchrones et des callbacks.<br />
<br />
Il existe un <a href="http://bit.ly/2aHNq4R" target="_blank"><u>outil en ligne</u></a> sur le Web qui permet de visualiser dynamiquement le déroulement d'un code asynchrone. Son auteur, Philip Roberts, explique en anglais plus en détail le fonctionnement de l'asynchrone dans cette vidéo ci-dessous et dont cet article s'est largement inspiré.<br />
<br />
<div style="text-align: center;">
<div class="video-container"><iframe class="restrain" title="YouTube video player" width="560" height="315" allowfullscreen src="//www.youtube.com/embed/8aGhZQkoFbQ?wmode=transparent&amp;fs=1" frameborder="0"></iframe></div>
</div><br />
N'hésitez pas à partager ce billet si vous l'avez trouvé utile.<br />
<br />
Bon développement !</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1546/bases-l-asynchrone-javascript/</guid>
		</item>
		<item>
			<title>Ecrire une application NodeJS avec TypeScript</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1542/ecrire-application-nodejs-typescript/</link>
			<pubDate>Mon, 25 Jul 2016 07:00:00 GMT</pubDate>
			<description>Pièce jointe 216200...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="https://www.developpez.net/forums/attachments/p216200d1469293731/c-cpp/outils-c-cpp/cppbuilder/recuperer-resolution-l-ecran/langfr-170px-node.js_logo.svg.png/" border="0" alt="Nom : langfr-170px-Node.js_logo.svg.png
Affichages : 23588
Taille : 6,1 Ko"  style="float: CONFIG" />    <img src="http://www.developpez.net/forums/attachments/p156011d1410504996/webmasters-developpement-web-9/javascript-ajax-typescript-dart-2000/typescript-2001/typescript-annonce-nouveau-compilateur/logo-typescript.png/" border="0" alt="" /></div><br />
<br />
<b><font size="4">1. Introduction</font></b><br />
<br />
Le langage TypeScript est un surensemble typé de JavaScript dont la philosophie n'est pas de remplacer JavaScript, mais de se poser en véritable complément.<br />
<br />
Pour illustrer ce propos, regardons comment utiliser TypeScript pour monter un petit serveur sous NodeJS.<br />
<br />
Le code source de ce projet est disponible sur le <b><a href="https://github.com/yahiko00/SimpleNodeApp" target="_blank">dépôt GitHub</a></b> suivant : <a href="https://github.com/yahiko00/SimpleNodeApp" target="_blank">https://github.com/yahiko00/SimpleNodeApp</a><br />
<br />
<br />
<b><font size="4">2. Mise en place de l'environnement de travail</font></b><br />
<br />
Pour cet article, l'environnement de travail que nous allons mettre en place se compose de trois volets : l'organisation des répertoires, l'installation et la configuration de TypeScript et l'installation de NodeJS.<br />
<br />
<b><font size="3">2.1. Arborescence</font></b><br />
<br />
<b>Projet/<br />
<div style="margin-left:40px">build/   <font color="#0000CD">...</font><br />
node_modules/   <font color="#0000CD">...</font><br />
src/<br />
<font color="#0000CD"><div style="margin-left:40px">server.ts</div></font><br />
<font color="#0000CD">index.html</font><br />
<font color="#0000CD">tsconfig.json</font></div></b><br />
<br />
Le répertoire <i>Projet/</i> constituera la racine du projet où on trouvera les fichiers <i>index.html</i>, notre page Web, et <i>tsconfig.json</i> que nous verrons plus en détail un peu plus loin ; le répertoire <i>build/</i> sera là où sera généré le résultat de la compilation de TypeScript ; le répertoire <i>node_modules/</i>, généré par l'utilitaire npm, contiendra le &quot;liant&quot; entre TypeScript et NodeJS ; et le répertoire <i>src/</i> contiendra nos scripts.<br />
<br />
<b><font size="3">2.2. TypeScript</font></b><br />
<br />
Nous travaillerons avec la version 2.0 de TypeScript qui est actuellement en mode beta au moment où est écrit cet article. Pour l'installer, voici la ligne de commande :<br />
<div style="margin-left:40px"><b><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install typescript@beta -g</span></b></div><br />
Par la suite, lorsque cette version 2.0 (ou ultérieure) sera en production, il suffira de taper cette ligne de commande pour installer TypeScript :<br />
<div style="margin-left:40px"><b><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install typescript -g</span></b></div><br />
La configuration du compilateur TypeScript peut s'effectuer à différents endroits. Au niveau de l'EDI comme c'est le cas pour Visual Studio par exemple, au niveau de la ligne de commande avec les options de compilation ou au niveau d'un fichier projet qui se nomme par défaut <i>tsconfig.json</i>. Ce fichier doit se trouver à la racine du projet, dans notre cas <i>Projet/</i>. Un squelette de ce fichier projet peut être généré par le compilateur via la ligne de commande suivante :<br />
<div style="margin-left:40px"><b><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">tsc --init</span></b></div><br />
Pour les besoins de cet article, voici ce que doit contenir ce fichier :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// tsconfig.json</span>
&nbsp;
<span class="br0">&#123;</span>
    <span style="color: #FF0000;">&quot;compilerOptions&quot;</span>: <span class="br0">&#123;</span>
        <span style="color: #FF0000;">&quot;noImplicitAny&quot;</span>: <span style="color: #339933;">true</span>,
        <span style="color: #FF0000;">&quot;target&quot;</span>: <span style="color: #FF0000;">&quot;es5&quot;</span>,
        <span style="color: #FF0000;">&quot;module&quot;</span>: <span style="color: #FF0000;">&quot;commonjs&quot;</span>,
        <span style="color: #FF0000;">&quot;outDir&quot;</span>: <span style="color: #FF0000;">&quot;./build&quot;</span>
    <span class="br0">&#125;</span>,
    <span style="color: #FF0000;">&quot;exclude&quot;</span> : <span class="br0">&#91;</span>
        <span style="color: #FF0000;">&quot;./build&quot;</span>,
        <span style="color: #FF0000;">&quot;./node_modules&quot;</span>
    <span class="br0">&#93;</span>
<span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
<ul><li style="">Dans la section <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">compilerOptions</span>, l'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">noImplicitAny</span> indique que les déclarations non typées, comme par exemple <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">let x;</span>, ne seront pas permises.</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">target</span> permet de définir la version ECMAScript que doit générer TypeScript. Par défaut, c'est la version ES5.</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">module</span> permet de définir le format des modules à gérer par le compilateur aussi bien à l'importation qu'à la génération. Ici nous travaillerons avec le format CommonJS qui est celui de NodeJS, mais les formats AMD, SystemJS, UMD et ES2015 (ES6) sont également supportés.</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">outDir</span> définit un répertoire vers lequel seront générés les résultats de la compilation.</li><li style="">La section <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">exclude</span> définit les répertoires et les fichiers à exclure du projet. Ici, on souhaite ignorer les fichiers se trouvant dans le répertoire de sortie <i>build/</i> et les bibliothèques rapatriées via npm qui se retrouveront dans le répertoire <i>node_modules/</i>.</li></ul><br />
<br />
Pour avoir la liste exhaustive des options disponibles dans <i>tsconfig.json</i>, on peut simplement afficher l'aide du compilateur via la commande <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">tsc -h</span>, dans la mesure où <i>tsconfig.json</i> reprend toutes les options du compilateur, à de rares exceptions près. On peut également se reporter à la page suivante, même si sa mise à jour est souvent en décalage avec la dernière version de TypeScript.<br />
<br />
<b><font size="3">2.3. NodeJS</font></b><br />
<br />
Si ce n'est pas déjà fait, il convient d'installer NodeJS en le téléchargeant au <b><a href="https://nodejs.org/en/download/" target="_blank">lien suivant</a></b> : <a href="https://nodejs.org/en/download/" target="_blank">https://nodejs.org/en/download/</a><br />
<br />
Afin que TypeScript puisse correctement exploiter l'API de NodeJS écrite en JavaScript, il est nécessaire de lui fournir un fichier de définitions de types au format <i>.d.ts</i>. Heureusement, pour la plupart des bibliothèques et frameworks un minimum diffusés, il existe de tels fichiers de définition prêts à l'emploi. Grâce à la version 2.0, une simple commande npm suffit à rapatrier le fichier de définition dont nous avons besoin :<br />
<div style="margin-left:40px"><b><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install @types/node</span></b></div><br />
Cela téléchargera le fichier de définition de types <i>.d.ts</i> pour NodeJS dans le répertoire standard <i>Projet/node_modules/@types/</i>. Si notre éditeur exploite correctement la fonctionnalité de découverte automatique des fichiers de définitions de types fournie par l'API du compilateur, et c'est le cas notamment pour Visual Studio et Visual Studio Code, alors nous n'avons rien d'autre à faire pour utiliser NodeJS dans notre projet TypeScript.<br />
<br />
Maintenant que notre environnement de travail est prêt, voyons à quoi ressemble le code.<br />
<br />
<br />
<b><font size="4">3. Serveur NodeJS minimaliste</font></b><br />
<br />
Notre serveur NodeJS se contentera du minimum. Il traitera n'importe quelle requête de la même façon en affichant le contenu de la page HTML <i>index.html</i>. Ce n'est évidemment que juste pour l'exemple.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code html :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:156px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #339933;">&lt;!DOCTYPE html&gt;</span>
<span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">html</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">meta</span> <span style="color: #0080ff;">charset</span><span style="color: #0000ff;">=</span><span style="color: #FF0000;">&quot;utf-8&quot;</span><span style="color: #0000ff;">&gt;</span></span> 
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">head</span><span style="color: #0000ff;">&gt;</span></span>
        <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">title</span><span style="color: #0000ff;">&gt;</span></span>Simple nodeJS application in TypeScript<span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">title</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">head</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">body</span><span style="color: #0000ff;">&gt;</span></span>
        <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">h1</span><span style="color: #0000ff;">&gt;</span></span>Simple nodeJS application in TypeScript<span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">h1</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">body</span><span style="color: #0000ff;">&gt;</span></span>
<span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">html</span><span style="color: #0000ff;">&gt;</span></span></pre></td></tr></table></pre>
</div><br />
Voici le programme principal NodeJS :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// server.ts</span>
&nbsp;
<span style="color: #0000ff;">import</span> http <span style="color: black;">=</span> <span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'http'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: #0000ff;">import</span> os <span style="color: black;">=</span> <span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'os'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: #0000ff;">import</span> fs <span style="color: black;">=</span> <span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'fs'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">class</span> HttpServer <span style="color: black;">&#123;</span>
    nodePort<span style="color: black;">:</span> <span style="color: #0080ff;">number</span><span style="color: black;">;</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">constructor</span> <span style="color: black;">&#40;</span>port<span style="color: black;">:</span> <span style="color: #0080ff;">number</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">nodePort</span> <span style="color: black;">=</span> port<span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    onRequest<span style="color: black;">&#40;</span>request<span style="color: black;">:</span> http.<span style="color: #0080ff;">ServerRequest</span><span style="color: black;">,</span> response<span style="color: black;">:</span> http.<span style="color: #0080ff;">ServerResponse</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'New request: '</span> <span style="color: black;">+</span> request.<span style="color: #0080ff;">url</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
        fs.<span style="color: #0080ff;">readFile</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'./index.html'</span><span style="color: black;">,</span> <span style="color: black;">&#40;</span>err<span style="color: black;">:</span> Error<span style="color: black;">,</span> data<span style="color: black;">:</span> Buffer<span style="color: black;">&#41;</span> <span style="color: black;">=&gt;</span> <span style="color: black;">&#123;</span>
            <span style="color: #0000ff;">if</span> <span style="color: black;">&#40;</span>err<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
                <span style="color: #0000ff;">throw</span> err<span style="color: black;">;</span>
            <span style="color: black;">&#125;</span>
            response.<span style="color: #0080ff;">writeHead</span><span style="color: black;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: black;">,</span> <span style="color: black;">&#123;</span><span style="color: #FF0000;">'Content-Type'</span><span style="color: black;">:</span> <span style="color: #FF0000;">'text/html'</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
            response.<span style="color: #0080ff;">write</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span><span style="color: black;">;</span>
            response.<span style="color: #0080ff;">end</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    onStart<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;font-weight:bold">let</span> httpServer <span style="color: black;">=</span> http.<span style="color: #0080ff;">createServer</span><span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">onRequest</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        httpServer.<span style="color: #0080ff;">listen</span><span style="color: black;">&#40;</span><span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">nodePort</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'Server listenning on http://'</span> <span style="color: black;">+</span> os.<span style="color: #0080ff;">hostname</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">+</span> <span style="color: #FF0000;">':'</span> <span style="color: black;">+</span> <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">nodePort</span> <span style="color: black;">+</span> <span style="color: #FF0000;">'/'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">let</span> server <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> HttpServer<span style="color: black;">&#40;</span><span style="color: #cc66cc;">8080</span><span style="color: black;">&#41;</span>.<span style="color: #0080ff;">onStart</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
On peut constater que le code est compréhensible au premier coup d’œil au point qu'on peut sans problème se passer de commentaires. L'organisation en classe permet de connaître rapidement les fonctionnalités disponibles et le typage permet de savoir ce qui est passé en paramètre des méthodes.<br />
<br />
L'importation des modules externes est fait avec la syntaxe TypeScript <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">import variable = require('module')</span> d'avant la norme ES2015, qui sera simplement transpilée au format CommonJS en <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">var variable = require('module')</span>.<br />
<br />
La classe <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">HttpServer</span> possède un constructeur qui initialise l'attribut <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">nodePort</span> qui sera le port d'écoute du serveur Node.<br />
<br />
Cette classe possède deux méthodes : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">onRequest()</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">onStart()</span>. La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">onRequest()</span> a pour tâche d'envoyer au client le contenu du fichier HTML <i>index.html</i>, et ce de façon inconditionnelle, sans tenir compte du type de requête reçue.<br />
<br />
La méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">onStart()</span> quant à elle lance le serveur sur le port défini via le constructeur. Elle est d'ailleurs appelée juste après l'instanciation de la classe <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">HttpServer</span>, à la dernière ligne.<br />
<br />
Après avoir compilé avec la commande <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">tsc</span>, il ne reste plus qu'à lancer le programme avec la commande suivante à la racine du projet :<br />
<div style="margin-left:40px"><b><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">node ./build/server.js</span></b></div><br />
Et sur notre navigateur, à l'adresse suivante, <a href="http://localhost:8080/" target="_blank">http://localhost:8080/</a>, nous devrions voir apparaître notre page <i>index.html</i>.<br />
<br />
<br />
<b><font size="4">4. Conclusion</font></b><br />
<br />
Voià ! Comme on vient de le voir, utiliser NodeJS avec TypeScript est très simple. Tant dans la mise en place de l'environnement que dans l'écriture du code. Bien entendu, l'exemple que nous venons de voir peut largement être amélioré, mais la façon d'utiliser TypeScript avec NodeJS ne devrait pas fondamentalement changer.<br />
<br />
Si vous avez trouvé ce billet utile, n'hésitez pas à le partager.<br />
<br />
Bon développement !</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1542/ecrire-application-nodejs-typescript/</guid>
		</item>
		<item>
			<title>Importation de modules externes en TypeScript</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1533/importation-modules-externes-typescript/</link>
			<pubDate>Fri, 22 Jul 2016 18:39:24 GMT</pubDate>
			<description>Image :...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="http://www.developpez.net/forums/attachments/p156011d1410504996/webmasters-developpement-web-9/javascript-ajax-typescript-dart-2000/typescript-2001/typescript-annonce-nouveau-compilateur/logo-typescript.png/" border="0" alt="" /></div><br />
<b>Sommaire</b><br />
<br />
1. Introduction<br />
2. Mise en place de l'environnement<br />
3. Squelette du projet<br />
4. Importation d'un module externe TypeScript<br />
5. Importation d'un module externe ES2015<br />
6. Importation d'un fichier JavaScript à plat<br />
7. Importation de bibliothèques JavaScript courantes<br />
<br />
<br />
<br />
<b><font size="4">1. Introduction</font></b><br />
<br />
TypeScript est un surensemble typé de JavaScript. C'est un langage <i>open source</i> conçu par Anders Hejlsberg qui a déjà les langages Turbo Pascal, Delphi et C# à son actif, excusez du peu. Nous supposerons dans cet article que le lecteur a déjà quelques notions de ce langage dont il pourra lire une introduction <b><a href="http://yahiko.developpez.com/tutoriels/introduction-typescript/" target="_blank">ici</a></b>.<br />
<br />
Cet article a pour objectif de faire un rapide tour d'horizon sur les possibilités d'importation des modules externes dans un projet TypeScript, ce qui est souvent un point de blocage lors de la découverte de ce langage.<br />
<br />
Par importation de modules externes, nous entendons importation dynamique de scripts et non pas d'inclusion de scripts via la balise HTML <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">&lt;script&gt;</span>.<br />
<br />
Il existe différents formats de modules JavaScript actuellement. TypeScript prend en charge les formats AMD, CommonJS, SystemJS, UMD et ES2015 (ES6). Nous supposerons également le lecteur familiarisé avec ces formats, et notamment AMD puisque c'est celui-ci qui nous servira de référence tout au long de notre présentation.<br />
<br />
Après avoir décrit le contexte de travail dans lequel se situeront nos exemples (arborescence projet, outils, configuration), nous présenterons trois cas standards d'importation de modules. Un premier cas pour le format natif de module dans TypeScript. Un second pour le format JavaScript/ES2015, mais dont la méthode peut s'appliquer aussi pour les formats de modules précités. Et enfin un troisième cas où nous n'importerons pas vraiment des modules, mais des scripts à plat.<br />
<br />
Enfin, nous terminerons cette présentation par un exemple d'importation des bibliothèques jQuery et underscore.<br />
<br />
A noter que tous les exemples de cet article peuvent être récupérés sur <b><a href="https://github.com/yahiko00/ImportationModules" target="_blank">mon dépôt GitHub</a></b> à l'adresse suivante : <a href="https://github.com/yahiko00/ImportationModules" target="_blank">https://github.com/yahiko00/ImportationModules</a><br />
<br />
<br />
<b><font size="4">2. Mise en place de l'environnement</font></b><br />
<br />
<b><font size="3">2.1. Arborescence du projet</font></b><br />
<br />
Tout au long de cet article, nous supposerons avoir l'arborescence suivante pour notre projet :<br />
<b>Projet/<br />
<div style="margin-left:40px">build/   <font color="#0000CD">...</font><br />
node_modules/<br />
<div style="margin-left:40px">@types/   <font color="#0000CD">...</font></div><div style="margin-left:40px">requirejs/</div><div style="margin-left:40px"><div style="margin-left:40px"><font color="#0000CD">require.js</font></div><div style="margin-left:40px"><font color="#0000CD">...</font></div></div>script/<br />
<div style="margin-left:40px"><font color="#0000CD">app.ts</font></div><div style="margin-left:40px"><font color="#0000CD">...</font></div><font color="#0000CD">index.html</font><br />
<font color="#0000CD">tsconfig.json</font></div></b><br />
<br />
Le répertoire <i>Projet/</i> constituera la racine du projet où on trouvera les fichiers <i>index.html</i>, notre page Web, et <i>tsconfig.json</i> que nous verrons plus en détail un peu plus loin ; le répertoire <i>build/</i> sera là où sera généré le résultat de la compilation de TypeScript ; le répertoire <i>node_modules/</i>, généré par l'utilitaire <b>npm</b>, contiendra les différentes bibliothèques dont <b>RequireJS</b> qui permettra d'importer les modules au format AMD ; et le répertoire <i>script/</i> contiendra nos scripts.<br />
<br />
<b><font size="3">2.2. Installation des outils</font></b><br />
<br />
<b>EDI</b><br />
<br />
Le compilateur TypeScript est intégré à Visual Studio 2015 ce qui permet de s'initier à ce langage très rapidement. C'est aussi le cas de WebStorm qui est une référence dans les EDI orientés Web. Pour ce projet, nous utiliserons un éditeur plus léger ce qui aura le mérite de nous forcer à mettre un peu les mains dans le cambouis du fichier projet <i>tsconfig.json</i>. Il existe pléthore d'éditeurs sur le marché. Le choix ici se portera sur <b><a href="https://code.visualstudio.com/download" target="_blank">Visual Studio Code</a></b> dont l'interface graphique a été codée en TypeScript justement. Il a l'avantage d'être léger contrairement au mastodonte qu'est Visual Studio, multiplateformes (Windows, OS X et Linux), et offre un bon confort de programmation dans la mesure où il prend en charge le <i>Language Service</i>, l'API de TypeScript lui permettant de bénéficier entre autre de la coloration syntaxique, de l'autocomplétion intelligente, du refactoring ou la détection des erreurs à la volée. Toujours est il que ce qui sera présenté dans cet article restera globalement valable pour n'importe quel environnement de développement.<br />
<br />
<b>nodeJS</b><br />
Si ce n'est pas déjà fait, il sera préférable d'installer <b><a href="https://nodejs.org/en/download/" target="_blank">NodeJS</a></b> rien que pour son utilitaire de téléchargement de packages <b>npm</b> qui nous servira ici à installer le compilateur TypeScript et des bibliothèques JavaScript dans le dernier chapitre.<br />
<br />
<b>Compilateur TypeScript</b><br />
Pour installer la version de production de TypeScript (normalement déjà livrée avec Visual Studio Code), la ligne de commande est la suivante :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install -g typescript</b></span></div><br />
Pour installer la version <i>nigthly</i>, en cours de développement, la ligne de commande est la suivante :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install -g typescript@next</b></span></div><br />
A l'heure où est écrit cet article, la version 2.0 de TypeScript est en phase beta. Pour la télécharger, la ligne de commande est la suivante :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install -g typescript@beta</b></span></div><br />
Il est possible et recommandé de vérifier la version du compilateur via la ligne de commande suivante :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>tsc -v</b></span></div><br />
C'est avec cette version beta 2.0 sur laquelle seront basés les exemples de cet article. A noter que plusieurs versions du compilateur TypeScript peuvent très bien cohabiter, à condition de bien savoir quelle version est lancée à quel moment. Pour spécifier la version de TypeScript à prendre en compte par Visual Studio Code, on peut utilement se référer à <b><a href="http://www.developpez.net/forums/blogs/676693-yahiko/b1535/utiliser-visual-studio-code-version-typescript-plus-recente/" target="_blank">cet article</a></b>.<br />
<br />
<b>RequireJS</b><br />
<br />
Pour des raisons de simplicité, nos exemples seront basés sur les modules au format AMD dans un micro projet côté client. C'est pourquoi nous opterons ici pour la bibliothèque d'importation des modules <b>RequireJS</b>. Pour installer cette bibliothèque, voici la ligne de commande à exécuter à la racine <i>Projet/</i> :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install requirejs</b></span></div><br />
Suite à cela, nous devrions trouver le fichier <i>require.js</i> dans le répertoire <i>Projet/node_modules/requirejs/</i>.<br />
<br />
Afin que TypeScript puisse correctement exploiter cette bibliothèque écrite en JavaScript, il est nécessaire de lui fournir un fichier de définitions de types au format <i>.d.ts</i>. Heureusement, pour la plupart des bibliothèques et frameworks un minimum diffusés, il existe de tels fichiers de définition prêts à l'emploi. Grâce à la version 2.0, une simple commande npm suffit à rapatrier le fichier de définition dont nous avons besoin :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install @types/requirejs</b></span></div><br />
Cela téléchargera le fichier de définition <i>.d.ts</i> pour RequireJS dans le répertoire standard <i>Projet/node_modules/@types/</i>. Si notre éditeur exploite correctement la fonctionnalité de découverte automatique des fichiers de définitions de types fournie par l'API du compilateur, et c'est le cas notamment pour Visual Studio Code, alors nous n'avons rien d'autre à faire pour utiliser RequireJS dans notre projet TypeScript. C'est vraiment un gain de temps très appréciable comparé à la méthode DefinitelyTyped pour les connaisseurs.<br />
<br />
<b><font size="3">2.3. Configuration</font></b><br />
<br />
La configuration du compilateur TypeScript peut s'effectuer à différents endroits. Au niveau de l'EDI comme c'est le cas pour Visual Studio par exemple, au niveau de la ligne de commande avec les options de compilation ou au niveau d'un fichier projet qui se nomme par défaut <i>tsconfig.json</i>. Ce fichier doit se trouver à la racine du projet, dans notre cas <i>Projet/</i>. Un squelette de ce fichier projet peut être généré par le compilateur via la ligne de commande suivante :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>tsc --init</b></span></div><br />
Pour les besoins de cet article, voici ce que doit contenir ce fichier dans un premier temps :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// tsconfig.json</span>
&nbsp;
<span class="br0">&#123;</span>
    <span style="color: #FF0000;">&quot;compilerOptions&quot;</span>: <span class="br0">&#123;</span>
        <span style="color: #FF0000;">&quot;noImplicitAny&quot;</span>: <span style="color: #339933;">true</span>,
        <span style="color: #FF0000;">&quot;strictNullChecks&quot;</span>: <span style="color: #339933;">true</span>,
        <span style="color: #FF0000;">&quot;target&quot;</span>: <span style="color: #FF0000;">&quot;es5&quot;</span>,
        <span style="color: #FF0000;">&quot;module&quot;</span>: <span style="color: #FF0000;">&quot;amd&quot;</span>,
        <span style="color: #FF0000;">&quot;outDir&quot;</span>: <span style="color: #FF0000;">&quot;./build&quot;</span>
    <span class="br0">&#125;</span>,
    <span style="color: #FF0000;">&quot;exclude&quot;</span> : <span class="br0">&#91;</span>
        <span style="color: #FF0000;">&quot;./build&quot;</span>,
        <span style="color: #FF0000;">&quot;./node_modules&quot;</span>
    <span class="br0">&#93;</span>
<span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
<ul><li style="">Dans la section <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">compilerOptions</span>, l'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">noImplicitAny</span> indique que les déclarations non typées, comme par exemple <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">let x;</span>, ne seront pas permises.</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">strictNullChecks</span> qui vient d'arriver avec la version 2.0 indique que nous ne manipulons que des types non-nullifiables (cf. <a href="http://www.developpez.net/forums/d1594916/webmasters-developpement-web/javascript-ajax-typescript-dart/typescript/typescript-2-0-disponible-beta/" target="_blank">récapitulatif de la version 2.0</a>).</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">target</span> permet de définir la version ECMAScript que doit générer TypeScript. Par défaut, c'est la version ES5.</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">module</span> permet de définir le format des modules à gérer par le compilateur aussi bien à l'importation qu'à la génération. Ici nous travaillerons avec le format AMD, mais les formats CommonJS, SystemJS, UMD et ES2015 (ES6) sont également supportés.</li><li style="">L'option <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">outDir</span> définit un répertoire vers lequel seront générés les résultats de la compilation.</li><li style="">La section <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">exclude</span> définit les répertoires et les fichiers à exclure du projet. Ici, on souhaite ignorer les fichiers se trouvant dans le répertoire de sortie <i>build/</i> et les bibliothèques rapatriées via npm, comme RequireJS par exemple, qui se retrouveront dans le répertoire <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">node_modules/</span>.</li></ul><br />
<br />
Pour avoir la liste exhaustive des options disponibles dans <i>tsconfig.json</i>, on peut simplement afficher l'aide du compilateur via la commande <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">tsc -h</span>, dans la mesure où <i>tsconfig.json</i> reprend toutes les options du compilateur, à de rares exceptions près. On peut également se reporter à la <b><a href="https://www.typescriptlang.org/docs/handbook/compiler-options.html" target="_blank">page suivante</a></b>, même si sa mise à jour est souvent en décalage avec la dernière version de TypeScript.<br />
<br />
<br />
<b><font size="4">3. Squelette du projet</font></b><br />
<br />
Le point d'entrée de notre projet minimaliste sera une page Web pratiquement vide, <i>index.html</i>, dont le but sera juste de charger la bibliothèque <b>RequireJS</b> qui lancera un fichier JavaScript <i>config.js</i> (aussi souvent appelé <i>main.js</i>) qui aura pour responsabilité de charger les différents modules et dépendances du projet et de lancer l'application proprement dite.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code html :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #339933;">&lt;!DOCTYPE html&gt;</span>
<span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">html</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">meta</span> <span style="color: #0080ff;">charset</span><span style="color: #0000ff;">=</span><span style="color: #FF0000;">&quot;utf-8&quot;</span><span style="color: #0000ff;">&gt;</span></span> 
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">head</span><span style="color: #0000ff;">&gt;</span></span>
        <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">title</span><span style="color: #0000ff;">&gt;</span></span>Importation de modules externes en TypeScript<span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">title</span><span style="color: #0000ff;">&gt;</span></span>
        <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">script</span> data-main<span style="color: #0000ff;">=</span><span style="color: #FF0000;">&quot;build/config.js&quot;</span> <span style="color: #0080ff;">src</span><span style="color: #0000ff;">=</span><span style="color: #FF0000;">&quot;node_modules/requirejs/require.js&quot;</span><span style="color: #0000ff;">&gt;</span></span><span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">script</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">head</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">body</span><span style="color: #0000ff;">&gt;</span></span>
        <span style="color: #339933;"><span style="color: #0000ff;">&lt;</span><span style="color: #0000ff;">h1</span><span style="color: #0000ff;">&gt;</span></span>Importation de modules externes en TypeScript<span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">h1</span><span style="color: #0000ff;">&gt;</span></span>
    <span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">body</span><span style="color: #0000ff;">&gt;</span></span>
<span style="color: #339933;"><span style="color: #0000ff;">&lt;/</span><span style="color: #0000ff;">html</span><span style="color: #0000ff;">&gt;</span></span></pre></td></tr></table></pre>
</div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:192px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// config.ts</span>
&nbsp;
<span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span>
    <span style="color: black;">&#91;</span><span style="color: #FF0000;">'app'</span><span style="color: black;">&#93;</span><span style="color: black;">,</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">function</span> <span style="color: black;">&#40;</span>app<span style="color: black;">:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        app.<span style="color: #0080ff;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">,</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">function</span> <span style="color: black;">&#40;</span>err<span style="color: black;">:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        console.<span style="color: #0080ff;">error</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'ERROR: '</span><span style="color: black;">,</span> err.<span style="color: #0080ff;">requireType</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        console.<span style="color: #0080ff;">error</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'MODULES: '</span><span style="color: black;">,</span> err.<span style="color: #0080ff;">requireModules</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#41;</span><span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
Ce fichier <i>config.ts</i> (en réalité, <i>config.js</i> lorsqu'il sera compilé en JavaScript) lancera le programme <i>app.ts</i> (en réalité, <i>app.js</i> lorsqu'il sera compilé en JavaScript) via une méthode <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">start()</span>.<br />
<br />
Sur le <a href="http://requirejs.org/" target="_blank">site officiel de RequireJS</a>, on trouvera toutes les informations utiles concernant la structure de ce programme d'initialisation et sur les modules AMD en général.<br />
<br />
<br />
<b><font size="4">4. Importation d'un module externe TypeScript</font></b><br />
<br />
<b><font size="3">4.1. Programme principal</font></b><br />
<br />
Dans un premier exemple, nous allons voir comment importer dans notre petite application <i>app.ts</i> un module externe au format natif de TypeScript. C'est le cas le plus simple.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// app.ts</span>
&nbsp;
<span style="color: #0000ff;">import</span> <span style="color: black;">*</span> <span style="color: #0000ff;font-weight:bold">as</span> Animal <span style="color: #0000ff;">from</span> <span style="color: #FF0000;">&quot;animal&quot;</span><span style="color: black;">;</span> <span style="color: #808080;">// Module TS</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">function</span> start<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    <span style="color: #0000ff;font-weight:bold">let</span> garry <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Animal.<span style="color: #0080ff;">Snail</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'Garry'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">let</span> simbad <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Animal.<span style="color: #0080ff;">Lion</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'Simbad'</span><span style="color: black;">,</span> Animal.<span style="color: #0080ff;">Sex</span>.<span style="color: #0080ff;">MALE</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
    console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>garry.<span style="color: #0080ff;">name</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>simbad.<span style="color: #0080ff;">name</span><span style="color: black;">,</span> simbad.<span style="color: #0080ff;">sex</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
Dans le code ci-dessus, nous pouvons distinguer deux parties. La première avec l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">import</span> qui demande au compilateur de rechercher un module externe <i>animal.ts</i> et de rapatrier tous les membres accessibles (exportés) dans une nouvelle variable <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Animal</span>. Cette syntaxe est celle de la nouvelle norme ES2015 mise en place depuis la version 1.5 de TypeScript. Même si l'ancienne est toujours possible, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">import Animal = require(&quot;animal&quot;)</span>, il est préférable d'utiliser la nouvelle syntaxe, quand c'est possible. Ce qui ne sera pas toujours le cas, comme nous le verrons par la suite.<br />
<br />
Notons que n'avons pas précisé de chemin pour le module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">animal</span>. On parle dans ce cas d'importation non-relative. Dans le mode de résolution des modules par défaut (<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--moduleResolution classic</span>), le compilateur cherche tout d'abord le module à importer <i>animal.ts</i> dans le même répertoire que le programme appelant <i>app.ts</i>, puis remonte l'arborescence, parent après parent, jusqu'à la racine <b><i>/</i></b>.<br />
<br />
Si nous avions écrit <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">import * as Animal from &quot;./animal&quot;</span>, alors nous aurions eu affaire à une importation relative. Et dans le mode de résolution des modules par défaut, le compilateur aurait cherché le module à importer <i>animal.ts</i> dans le même répertoire que le programme appelant <i>app.ts</i>, et c'est tout.<br />
<br />
Il existe de nombreuses variations à la résolution de module. Les traiter en détail dans cet article nous emmènerait trop loin. Mentionnons simplement qu'il existe un autre mode de résolution des modules basé sur la logique de nodeJS (<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--moduleResolution node</span>). Et que la version 2.0 a introduit les options de compilation <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--baseUrl</span>, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--paths</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--rootDirs</span>, également disponibles dans le fichier projet <i>tsconfig.json</i>, qui permettent d'avoir un large contrôle sur l'emplacement des modules.<br />
<br />
La seconde partie avec <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">export</span>, indique au compilateur TypeScript que le fichier <i>app.ts</i> doit également être considéré comme un module (et donc transformé en conséquence lors de la génération en JavaScript) et que la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">start()</span> sera accessible par les programmes qui importeront ce fichier, comme c'est le cas par exemple du programme de chargement des modules AMD <i>config.ts</i>.<br />
<br />
Jetons maintenant un œil sur le module <i>animal.ts</i>.<br />
<br />
<b><font size="3">4.2. Module externe TypeScript</font></b><br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// animal.ts</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">abstract</span> <span style="color: #0000ff;font-weight:bold">class</span> Animal <span style="color: black;">&#123;</span>
    name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
      <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">name</span> <span style="color: black;">=</span> name<span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">abstract</span> shout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">class</span> Snail <span style="color: #0000ff;font-weight:bold">extends</span> Animal <span style="color: black;">&#123;</span>
    shout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">'...'</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">enum</span> Sex <span style="color: black;">&#123;</span> MALE<span style="color: black;">,</span> FEMALE <span style="color: black;">&#125;</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">class</span> Lion <span style="color: #0000ff;font-weight:bold">extends</span> Animal <span style="color: black;">&#123;</span>
    sex<span style="color: black;">:</span> Sex<span style="color: black;">;</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">,</span> sex<span style="color: black;">:</span> Sex<span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">super</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span><span style="color: black;">;</span>
        <span style="color: #0000ff;font-weight:bold">this</span>.<span style="color: #0080ff;">sex</span> <span style="color: black;">=</span> sex<span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    shout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">:</span> <span style="color: #0080ff;">string</span> <span style="color: black;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">'Rooooaarrr!'</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
Le code ci-dessus n'a rien de bien particulier. Il s'agit juste pour l'exemple d'une petite hiérarchie de classes où sont exportées via l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">export</span>, les classes <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Animal</span>, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Snail</span> et <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Lion</span>, ainsi que l'énumération <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Sex</span>.<br />
<br />
<b><font size="3">4.3. Résultat de la compilation</font></b><br />
<br />
Pour compiler notre projet, il suffit de se placer à la racine de notre projet, ie. le répertoire <i>Projet/</i>, au même niveau que le fichier <i>tsconfig.json</i> en fait, et de lancer tout simplement <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>tsc</b></span> en ligne de commande.<br />
<br />
A l'issue de la compilation, voici l'arborescence que nous devrions obtenir :<br />
<br />
<b>Projet/<br />
<div style="margin-left:40px">build/<br />
<div style="margin-left:40px"><font color="#0000CD">animal.js<br />
app.js<br />
config.js</font></div>node_modules/<br />
<div style="margin-left:40px">@types/   <font color="#0000CD">...</font></div><div style="margin-left:40px">requirejs/</div><div style="margin-left:40px"><div style="margin-left:40px"><font color="#0000CD">require.js</font></div><div style="margin-left:40px"><font color="#0000CD">...</font></div></div>script/<br />
<div style="margin-left:40px"><font color="#0000CD">animal.ts<br />
app.ts<br />
config.ts</font></div><font color="#0000CD">index.html</font><br />
<font color="#0000CD">tsconfig.json</font></div></b><br />
<br />
Comme attendu, nos trois fichiers TypeScript <i>.ts</i> dans le répertoire <i>script/</i> ont été transpilés en fichiers JavaScript ES5 <i>.js</i> dans le répertoire <i>build/</i>.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:180px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// app.js</span>
&nbsp;
<span style="color: #0080ff;">define</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #FF0000;">&quot;require&quot;</span>, <span style="color: #FF0000;">&quot;exports&quot;</span>, <span style="color: #FF0000;">'animal'</span><span class="br0">&#93;</span>, <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>require, exports, Animal<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #FF0000;">&quot;use strict&quot;</span>;
    <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">var</span> garry = <span style="color: #0000ff;">new</span> Animal.<span style="color: #0080ff;">Snail</span><span class="br0">&#40;</span><span style="color: #FF0000;">'Garry'</span><span class="br0">&#41;</span>;
        <span style="color: #0000ff;">var</span> simbad = <span style="color: #0000ff;">new</span> Animal.<span style="color: #0080ff;">Lion</span><span class="br0">&#40;</span><span style="color: #FF0000;">'Simbad'</span>, Animal.Sex.male<span class="br0">&#41;</span>;
        console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span>garry.<span style="color: #0080ff;">name</span><span class="br0">&#41;</span>;
        console.<span style="color: #0080ff;">log</span><span class="br0">&#40;</span>simbad.<span style="color: #0080ff;">name</span>, simbad.sex<span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
    exports.start = start;
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
Ci-dessus, nous pouvons remarquer que la dépendance d'importation du module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">animal</span> a bien été prise en compte dans la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">define()</span> lors de la transformation du fichier <i>app.ts</i> en module AMD.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// animal.js</span>
&nbsp;
<span style="color: #0000ff;">var</span> __extends = <span class="br0">&#40;</span><span style="color: #0000ff;">this</span> &amp;&amp; <span style="color: #0000ff;">this</span>.__extends<span class="br0">&#41;</span> || <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>d, b<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0000ff;">for</span> <span class="br0">&#40;</span><span style="color: #0000ff;">var</span> p <span style="color: #0000ff;">in</span> b<span class="br0">&#41;</span> <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>b.<span style="color: #0080ff;">hasOwnProperty</span><span class="br0">&#40;</span>p<span class="br0">&#41;</span><span class="br0">&#41;</span> d<span class="br0">&#91;</span>p<span class="br0">&#93;</span> = b<span class="br0">&#91;</span>p<span class="br0">&#93;</span>;
    <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">__</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span style="color: #0000ff;">this</span>.<span style="color: #0080ff;">constructor</span> = d; <span class="br0">&#125;</span>
    d.<span style="color: #0000ff;">prototype</span> = b === <span style="color: #339933;">null</span> ? <span style="color: #0080ff;">Object</span>.<span style="color: #0080ff;">create</span><span class="br0">&#40;</span>b<span class="br0">&#41;</span> : <span class="br0">&#40;</span>__.<span style="color: #0000ff;">prototype</span> = b.<span style="color: #0000ff;">prototype</span>, <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">__</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>;
<span style="color: #0080ff;">define</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #FF0000;">&quot;require&quot;</span>, <span style="color: #FF0000;">&quot;exports&quot;</span><span class="br0">&#93;</span>, <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>require, exports<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #FF0000;">&quot;use strict&quot;</span>;
    <span style="color: #0000ff;">var</span> Animal = <span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">Animal</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">this</span>.<span style="color: #0080ff;">name</span> = <span style="color: #0080ff;">name</span>;
        <span class="br0">&#125;</span>
        <span style="color: #0000ff;">return</span> Animal;
    <span class="br0">&#125;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
    <span style="color: #0000ff;">var</span> Snail = <span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>_super<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0080ff;">__extends</span><span class="br0">&#40;</span>Snail, _super<span class="br0">&#41;</span>;
        <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">Snail</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            _super.<span style="color: #0080ff;">apply</span><span class="br0">&#40;</span><span style="color: #0000ff;">this</span>, arguments<span class="br0">&#41;</span>;
        <span class="br0">&#125;</span>
        Snail.<span style="color: #0000ff;">prototype</span>.shout = <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">'...'</span>;
        <span class="br0">&#125;</span>;
        <span style="color: #0000ff;">return</span> Snail;
    <span class="br0">&#125;</span><span class="br0">&#40;</span>Animal<span class="br0">&#41;</span><span class="br0">&#41;</span>;
    exports.Snail = Snail;
    <span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>Sex<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        Sex<span class="br0">&#91;</span>Sex<span class="br0">&#91;</span><span style="color: #FF0000;">&quot;male&quot;</span><span class="br0">&#93;</span> = <span style="color: #cc66cc;">0</span><span class="br0">&#93;</span> = <span style="color: #FF0000;">&quot;male&quot;</span>;
        Sex<span class="br0">&#91;</span>Sex<span class="br0">&#91;</span><span style="color: #FF0000;">&quot;female&quot;</span><span class="br0">&#93;</span> = <span style="color: #cc66cc;">1</span><span class="br0">&#93;</span> = <span style="color: #FF0000;">&quot;female&quot;</span>;
    <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span>exports.Sex || <span class="br0">&#40;</span>exports.Sex = <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
    <span style="color: #0000ff;">var</span> Sex = exports.Sex;
    ;
    <span style="color: #0000ff;">var</span> Lion = <span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>_super<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0080ff;">__extends</span><span class="br0">&#40;</span>Lion, _super<span class="br0">&#41;</span>;
        <span style="color: #0000ff;">function</span> <span style="color: #0080ff;">Lion</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span>, sex<span class="br0">&#41;</span> <span class="br0">&#123;</span>
            _super.<span style="color: #0080ff;">call</span><span class="br0">&#40;</span><span style="color: #0000ff;">this</span>, <span style="color: #0080ff;">name</span><span class="br0">&#41;</span>;
            <span style="color: #0000ff;">this</span>.sex = sex;
        <span class="br0">&#125;</span>
        Lion.<span style="color: #0000ff;">prototype</span>.shout = <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
            <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">'Rooooaarrr!'</span>;
        <span class="br0">&#125;</span>;
        <span style="color: #0000ff;">return</span> Lion;
    <span class="br0">&#125;</span><span class="br0">&#40;</span>Animal<span class="br0">&#41;</span><span class="br0">&#41;</span>;
    exports.Lion = Lion;
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
Le fichier <i>animal.js</i> est la transpilation ES5/AMD du module <i>animal.ts</i>.<br />
Enfin, pour la forme le fichier <i>config.js</i> ci-dessous, mais qui est pratiquement identique à sa source TypeScript.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:132px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// config.js</span>
&nbsp;
<span style="color: #0080ff;">require</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span style="color: #FF0000;">'app'</span><span class="br0">&#93;</span>, <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>app<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    app.<span style="color: #0080ff;">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>, <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>err<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    console.<span style="color: #0080ff;">error</span><span class="br0">&#40;</span><span style="color: #FF0000;">'ERROR: '</span>, err.requireType<span class="br0">&#41;</span>;
    console.<span style="color: #0080ff;">error</span><span class="br0">&#40;</span><span style="color: #FF0000;">'MODULES: '</span>, err.requireModules<span class="br0">&#41;</span>;
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
On constate donc qu'il est tout à fait possible et même très facile d'intégrer sous la forme de modules un sous-projet TypeScript à un projet plus global basé lui sur du JavaScript. Maintenant, examinons comment faire l'inverse, à savoir intégrer des modules JavaScript à une application TypeScript.<br />
<br />
<br />
<b><font size="4">5. Importation d'un module externe ES2015</font></b><br />
<br />
<b><font size="3">5.1. Module externe JavaScript ES1025</font></b><br />
<br />
Il est tout à fait possible d'importer des modules externes écrits nativement en JavaScript.<br />
<br />
Considérons en entrée le module <i>animal.js</i> suivant :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// animal.js</span>
&nbsp;
<span style="color: #0000ff;">export</span> <span style="color: #0000ff;">class</span> Animal <span class="br0">&#123;</span>
    <span style="color: #0080ff;">constructor</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
      <span style="color: #0000ff;">this</span>.<span style="color: #0080ff;">name</span> = <span style="color: #0080ff;">name</span>;
    <span class="br0">&#125;</span>
&nbsp;
    <span style="color: #0080ff;">shout</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #0000ff;">export</span> <span style="color: #0000ff;">class</span> Snail <span style="color: #0000ff;">extends</span> Animal <span class="br0">&#123;</span>
    <span style="color: #0080ff;">shout</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">'...'</span>;
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #0000ff;">export</span> <span style="color: #0000ff;">const</span> Sex = <span class="br0">&#123;</span> <span style="color: #800000;">MALE</span>: <span style="color: #cc66cc;">0</span>, <span style="color: #800000;">FEMALE</span>: <span style="color: #cc66cc;">1</span> <span class="br0">&#125;</span>;
&nbsp;
<span style="color: #0000ff;">export</span> <span style="color: #0000ff;">class</span> Lion <span style="color: #0000ff;">extends</span> Animal <span class="br0">&#123;</span>
    <span style="color: #0080ff;">constructor</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span>, sex<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0080ff;">super</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span><span class="br0">&#41;</span>;
        <span style="color: #0000ff;">this</span>.sex = sex;
    <span class="br0">&#125;</span>
&nbsp;
    <span style="color: #0080ff;">shout</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">'Rooooaarrr!'</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
Tout d'abord, il s'agit bien d'un fichier JavaScript, et pas d'un fichier TypeScript. Il est simplement écrit avec la norme ES2015 et nous permet de bénéficier de la syntaxe des classes et surtout dans notre situation de la nouvelle syntaxe des modules, identique à celle de TypeScript, plus intuitive à mon sens que les formats existants AMD, CommonJS ou UMD. A la charge du compilateur TypeScript de faire tout seule la transpilation en ES5 et d'emballer le code dans le format de module de notre choix, sans nécessiter un autre transpileur comme Babel.<br />
<br />
Cependant, comme il n'y a pas de magie, nous devons fournir une définition de type à ce fichier JavaScript. Cela n'a rien de très compliqué, d'autant qu'ici nous avons une forme déjà proche de TypeScript. Il ne manque finalement que les annotations de types.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// animal.d.ts</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">abstract</span> <span style="color: #0000ff;font-weight:bold">class</span> Animal <span style="color: black;">&#123;</span>
    name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">abstract</span> shout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">class</span> Snail <span style="color: #0000ff;font-weight:bold">extends</span> Animal <span style="color: black;">&#123;</span>
    shout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">enum</span> Sex <span style="color: black;">&#123;</span> MALE<span style="color: black;">,</span> FEMALE <span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">class</span> Lion <span style="color: #0000ff;font-weight:bold">extends</span> Animal <span style="color: black;">&#123;</span>
    sex<span style="color: black;">:</span> Sex<span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">,</span> sex<span style="color: black;">:</span> Sex<span style="color: black;">&#41;</span><span style="color: black;">;</span>
    shout<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
Le mot-clé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">déclare</span> indique au compilateur que ce qui suit existera bel et bien au moment de l'exécution, mais n'est pas immédiatement disponible pour le compilateur. C'est en effet notre cas puisque la concrétisation de ce qui est décrit dans ce fichier est au format JavaScript, et dont le contenu ne sera pleinement accessible qu'à l'exécution, au sein de la page HTML. On peut voir ça comme une sorte de promesse faite par le développeur envers le compilateur. Une analogie avec le langage C/C++ serait le mot-clé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">extern</span>.<br />
<br />
Depuis la version 2.0 de TypeScript, nous aurions pu nous passer d'un fichier de définition de types comme ci-dessus. Nous aurions bien eu accès aux classes et à leurs propriétés, mais ces dernières seraient restées non typées (<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">any</span>). Cela peut être une approche valable lors d'une première prise en charge d'un module JavaScript, même si à terme, il reste préférable de passer par un fichier de définition de types <i>.d.ts</i>.<br />
<br />
<b><font size="3">5.2. Programme principal</font></b><br />
<br />
A partir d'un tel module <i>animal.js</i>, le code de l'application <i>app.ts</i> est strictement identique à celui du chapitre précédent.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:168px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// app.ts</span>
&nbsp;
<span style="color: #0000ff;">import</span> <span style="color: black;">*</span> <span style="color: #0000ff;font-weight:bold">as</span> Animal <span style="color: #0000ff;">from</span> <span style="color: #FF0000;">&quot;animal&quot;</span><span style="color: black;">;</span> <span style="color: #808080;">// Module ES2015</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">function</span> start<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    <span style="color: #0000ff;font-weight:bold">let</span> garry <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Animal.<span style="color: #0080ff;">Snail</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'Garry'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">let</span> simbad <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Animal.<span style="color: #0080ff;">Lion</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'Simbad'</span><span style="color: black;">,</span> Animal.<span style="color: #0080ff;">Sex</span>.<span style="color: #0080ff;">MALE</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
    console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>garry.<span style="color: #0080ff;">name</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>simbad.<span style="color: #0080ff;">name</span><span style="color: black;">,</span> simbad.<span style="color: #0080ff;">sex</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
Notons cependant que le module animal qui est mentionné dans la clause <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">import</span>, ne correspond plus au fichier <i>animal.ts</i> comme au chapitre précédent, puisque celui-ci n'existe pas ici, mais au fichier <i>animal.d.ts</i> qui fait office de contrat. Nous assurons à TypeScript qu'un module tel que décrit dans <i>animal.d.ts</i> sera présent lors de l'exécution de l'application.<br />
<br />
<b><font size="3">5.3. Résultat de la compilation</font></b><br />
<br />
Lorsque nous lançons la compilation, aucune erreur ne se produit, mais nous pouvons constater un souci. Aucun fichier animal.js dans le répertoire cible <i>build/</i>. En effet, par défaut, le compilateur TypeScript ne traite pas les fichiers JavaScript en entrée. Il faut lui indiquer à l'aide de l'option de compilation <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--allowJs</span> que nous pouvons également inclure dans le fichier projet <i>tsconfig.json</i>.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// tsconfig.json</span>
&nbsp;
<span class="br0">&#123;</span>
    <span style="color: #FF0000;">&quot;compilerOptions&quot;</span>: <span class="br0">&#123;</span>
        <span style="color: #FF0000;">&quot;noImplicitAny&quot;</span>: <span style="color: #339933;">true</span>,
        <span style="color: #FF0000;">&quot;strictNullChecks&quot;</span>: <span style="color: #339933;">true</span>,
        <span style="color: #FF0000;">&quot;target&quot;</span>: <span style="color: #FF0000;">&quot;es5&quot;</span>,
        <span style="color: #FF0000;">&quot;module&quot;</span>: <span style="color: #FF0000;">&quot;amd&quot;</span>,
        <span style="color: #FF0000;">&quot;outDir&quot;</span>: <span style="color: #FF0000;">&quot;./build&quot;</span>,
        <span style="color: #FF0000;">&quot;allowJs&quot;</span>: <span style="color: #339933;">true</span>
    <span class="br0">&#125;</span>,
    <span style="color: #FF0000;">&quot;exclude&quot;</span> : <span class="br0">&#91;</span>
        <span style="color: #FF0000;">&quot;./build&quot;</span>,
        <span style="color: #FF0000;">&quot;./node_modules&quot;</span>
    <span class="br0">&#93;</span>
<span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
Une fois cette modification apportée au fichier <i>tsconfig.json</i>, le résultat de la compilation devrait donner l'arborescence suivante où on trouve bien un nouveau fichier <i>animal.js</i> en sortie dans le répertoire <i>build/</i> :<br />
<br />
<b>Projet/<br />
<div style="margin-left:40px">build/<br />
<div style="margin-left:40px"><font color="#0000CD">animal.js<br />
app.js<br />
config.js</font></div>node_modules/<br />
<div style="margin-left:40px">@types/   <font color="#0000CD">...</font></div><div style="margin-left:40px">requirejs/</div><div style="margin-left:40px"><div style="margin-left:40px"><font color="#0000CD">require.js</font></div><div style="margin-left:40px"><font color="#0000CD">...</font></div></div>script/<br />
<div style="margin-left:40px"><font color="#0000CD">animal.d.ts<br />
animal.js<br />
app.ts<br />
config.ts</font></div><font color="#0000CD">index.html</font><br />
<font color="#0000CD">tsconfig.json</font></div></b><br />
<br />
Nous venons ainsi d'importer un module nativement écrit en JavaScript, dans une application TypeScript. A noter que la démarche aurait été la même si le fichier <i>animal.js</i> en entrée avait été écrit en JavaScript ES5 avec une enveloppe AMD déjà présente. Pour s'en assurer, il suffit de remplacer le fichier <i>script/animal.js</i> par le fichier présent dans <i>build/animal.js</i> et constater que la compilation fonctionne parfaitement.<br />
<br />
A partir du moment que nous fournissons à TypeScript un module ayant une forme connu (AMD, CommonJS, UMD, ES2015) et qu'on lui associe un fichier de définition des types <i>.d.ts</i> convenable, le processus décrit dans ce chapitre s'applique à l'identique. A noter cependant qu'on ne peut pas avoir un module au format AMD en entrée et générer en sortie un module au format CommonJS. Ça ce n'est pas possible. Seul le format de module ES2015 (qui est le format de base TypeScript depuis la version 1.5) peut se convertir dans les autres formats de module.<br />
<br />
Maintenant, examinons un troisième cas d'importation, celui où le module en entrée, n'est en fait pas vraiment un module, mais un script &quot;à plat&quot;, sans enveloppe prédéfinie.<br />
<br />
<br />
<b><font size="4">6. Importation d'un fichier JavaScript à plat</font></b><br />
<br />
<b><font size="3">6.1. Scripts à plat</font></b><br />
<br />
Dans cet exemple, nous n'aurons non pas un mais deux fichiers à importer. Même s'ils seront dénommés modules par la suite, il faut bien noter qu'ils n'en ont pas la forme. Il s'agit juste de deux scripts à plat, sans enveloppe AMD ou autre.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:120px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// mineral.js</span>
&nbsp;
<span style="color: #0000ff;">class</span> Mineral <span class="br0">&#123;</span>
    <span style="color: #0080ff;">constructor</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">this</span>.<span style="color: #0080ff;">name</span> = <span style="color: #0080ff;">name</span>;
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:132px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// metal.js</span>
&nbsp;
<span style="color: #0000ff;">class</span> Metal <span style="color: #0000ff;">extends</span> Mineral <span class="br0">&#123;</span>
    <span style="color: #0080ff;">constructor</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span>, meltingPoint<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0080ff;">super</span><span class="br0">&#40;</span><span style="color: #0080ff;">name</span><span class="br0">&#41;</span>;
        <span style="color: #0000ff;">this</span>.meltingPoint = meltingPoint;
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
Comme pour tout fichier JavaScript en entrée, il convient de leur adjoindre deux fichiers de définition de types.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:132px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// mineral.d.ts</span>
&nbsp;
<span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">abstract</span> <span style="color: #0000ff;font-weight:bold">class</span> Mineral <span style="color: black;">&#123;</span>
    name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: black;">=</span> Mineral<span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:132px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// metal.d.ts</span>
&nbsp;
<span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">class</span> Metal <span style="color: #0000ff;font-weight:bold">extends</span> Mineral <span style="color: black;">&#123;</span>
    meltingPoint<span style="color: black;">:</span> <span style="color: #0080ff;">number</span><span style="color: black;">;</span>
    <span style="color: #0000ff;font-weight:bold">constructor</span><span style="color: black;">&#40;</span>name<span style="color: black;">:</span> <span style="color: #0080ff;">string</span><span style="color: black;">,</span> meltingPoint<span style="color: black;">:</span> <span style="color: #0080ff;">number</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: black;">=</span> Metal<span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
Notons dans ces fichiers de définition de types la présence à la fin de l'instruction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">export</span> suivi du symbole <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">=</span>. Cela signifie que dans le fichier <i>mineral.d.ts</i> (resp. <i>metal.d.ts</i>), <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Mineral</span> (resp. <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Metal</span>) est l'objet exporté par défaut. Ceci est la syntaxe TypeScript avant la prise en charge de la syntaxe ES2015 pour les modules (TypeScript 1.6).<br />
<br />
Nous ne pouvons malheureusement pas faire appel à la syntaxe ES2015 avec le mot-clé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">default</span> car il faut pour cela que l'enveloppe du module soit au format ES2015, ce qui n'est évidemment pas le cas ici puisque derrière ces fichiers de définition de types, nous avons des fichiers JavaScript à plat.<br />
<br />
<b><font size="3">6.2. Fichier de configuration RequireJS</font></b><br />
<br />
Dans la mesure où nous n'avons pas affaire à des modules AMD, nous devons expliciter à RequireJS les dépendances et les objets à exposer.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// config.ts</span>
&nbsp;
<span style="color: #0000ff;">require</span>.<span style="color: #0080ff;">config</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
    shim<span style="color: black;">:</span> <span style="color: black;">&#123;</span>
        <span style="color: #FF0000;">'mineral'</span><span style="color: black;">:</span> <span style="color: black;">&#123;</span>
            exports<span style="color: black;">:</span> <span style="color: #FF0000;">'Mineral'</span>
        <span style="color: black;">&#125;</span><span style="color: black;">,</span>
        <span style="color: #FF0000;">'metal'</span><span style="color: black;">:</span> <span style="color: black;">&#123;</span>
            deps<span style="color: black;">:</span> <span style="color: black;">&#91;</span><span style="color: #FF0000;">'mineral'</span><span style="color: black;">&#93;</span><span style="color: black;">,</span>
            exports<span style="color: black;">:</span> <span style="color: #FF0000;">'Metal'</span>
        <span style="color: black;">&#125;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span>
    <span style="color: black;">&#91;</span><span style="color: #FF0000;">'app'</span><span style="color: black;">&#93;</span><span style="color: black;">,</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">function</span> <span style="color: black;">&#40;</span>app<span style="color: black;">:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        app.<span style="color: #0080ff;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">,</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">function</span> <span style="color: black;">&#40;</span>err<span style="color: black;">:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        console.<span style="color: #0080ff;">error</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'ERROR: '</span><span style="color: black;">,</span> err.<span style="color: #0080ff;">requireType</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        console.<span style="color: #0080ff;">error</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'MODULES: '</span><span style="color: black;">,</span> err.<span style="color: #0080ff;">requireModules</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#41;</span><span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
Par rapport aux chapitres précédents, nous avons ajouté un appel à la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">require.config()</span> qui sert à paramétrer RequireJS. Le paramètre shim de l'objet passé en argument précise le comportement du chargeur de modules pour les scripts qui ne respecte pas le format AMD. Et c'est justement notre cas. Nous indiquons à RequireJS que <i>mineral.js</i> (resp. <i>metal.js</i>) doit exporter (<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">exports</span>) dans le contexte global <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">window</span>, l'objet <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Mineral</span> (resp. <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Metal</span>) puisqu'en JavaScript, une classe est une fonction qui est un objet. Nous indiquons également que le module <i>metal.js</i> dépend de <i>mineral.js</i> via le paramètre <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">deps</span>.<br />
<br />
Grâce à ces paramétrages, RequireJS chargera les scripts <i>mineral.js</i> et <i>metal.js</i> comme si c'étaient des modules AMD.<br />
<br />
<b><font size="3">6.3. Programme principal</font></b><br />
<br />
Nous pouvons donc désormais importer <i>metal.js</i> dans notre application via une clause <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">import</span> qui, comme pour la clause <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">export</span> vue précédemment, a ici une syntaxe différente de la norme ES2015 pour les modules.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// app.ts</span>
&nbsp;
<span style="color: #0000ff;">import</span> Metal <span style="color: black;">=</span> <span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'metal'</span><span style="color: black;">&#41;</span><span style="color: black;">;</span> <span style="color: #808080;">// JavaScript &agrave; plat</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">function</span> start<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    <span style="color: #0000ff;font-weight:bold">let</span> gold <span style="color: black;">=</span> <span style="color: #0000ff;font-weight:bold">new</span> Metal<span style="color: black;">&#40;</span><span style="color: #FF0000;">'Gold'</span><span style="color: black;">,</span> <span style="color: #cc66cc;">1064</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
    console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>gold.<span style="color: #0080ff;">name</span><span style="color: black;">,</span> gold.<span style="color: #0080ff;">meltingPoint</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
<b><font size="3">6.4. Résultat de la compilation</font></b><br />
<br />
La compilation transpile correctement en ES5 les fichiers JavaScript <i>mineral.js</i> et <i>metal.js</i>. Et bien que ceux-ci ne possèdent pas d'enveloppe AMD, la page Web se lance sans problème, grâce au fichier <i>config.js</i>.<br />
<br />
<b>Projet/<br />
<div style="margin-left:40px">build/<br />
<div style="margin-left:40px"><font color="#0000CD">app.js<br />
config.js<br />
metal.js<br />
mineral.js</font></div>node_modules/<br />
<div style="margin-left:40px">@types/   <font color="#0000CD">...</font></div><div style="margin-left:40px">requirejs/</div><div style="margin-left:40px"><div style="margin-left:40px"><font color="#0000CD">require.js</font></div><div style="margin-left:40px"><font color="#0000CD">...</font></div></div>script/<br />
<div style="margin-left:40px"><font color="#0000CD">app.ts<br />
config.ts<br />
metal.d.ts<br />
metal.js<br />
mineral.d.ts<br />
mineral.js</font></div><font color="#0000CD">index.html</font><br />
<font color="#0000CD">tsconfig.json</font></div></b><br />
<br />
<br />
<b><font size="4">7. Importation de bibliothèques JavaScript courantes</font></b><br />
<br />
Maintenant que nous avons vu les différentes manières pour importer des modules en TypeScript, nous pouvons appliquer ces méthodes pour importer des bibliothèques existantes et largement diffusées dans la communauté des développeurs Web. Dans cet exemple, nous allons montrer comment importer les bibliothèques jQuery et underscore.<br />
<br />
<b><font size="3">7.1. Installation des bibliothèques</font></b><br />
<br />
Pour installer jQuery et son fichier de définition de types, voici les lignes de commande à exécuter à la racine du projet :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install jquery</b></span></div><div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install @types/jquery</b></span></div><br />
Pour installer underscore et son fichier de définition de types, voici les lignes de commandes à exécuter à la racine du projet :<br />
<div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install underscore</b></span></div><div style="margin-left:40px"><span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block"><b>npm install @types/underscore</b></span></div><br />
Suite à cela, tout devrait avoir été installé dans des sous-répertoires de <i>node_modules/</i>.<br />
<br />
<b><font size="3">7.2. Programme principal</font></b><br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:144px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// app.ts</span>
&nbsp;
<span style="color: #0000ff;">import</span> $ <span style="color: black;">=</span> <span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;jquery&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: #0000ff;">import</span> _ <span style="color: black;">=</span> <span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;underscore&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;font-weight:bold">export</span> <span style="color: #0000ff;font-weight:bold">function</span> start<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
    $<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;h1&quot;</span><span style="color: black;">&#41;</span>.<span style="color: #0080ff;">hide</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    console.<span style="color: #0080ff;">log</span><span style="color: black;">&#40;</span>_.<span style="color: #0080ff;">isEmpty</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
Dans la mesure où les deux modules sont au format AMD, et non au format ES2015, nous devons utiliser l'ancienne syntaxe de TypeScript pour importer ces modules.<br />
<br />
En l'état, le compilateur devrait nous indiquer qu'il ne trouve pas le module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">underscore</span>, alors qu'étrangement il semble avoir localisé le module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">jquery</span>. Cette différence de traitement alors que les deux modules se trouvent à des endroits similaires, s'expliquent par le contenu de leur fichier de définition de types respectif, <i>index.d.ts</i>. Le fichier de définition de types du module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">jquery</span> déclare bien l'existence d'un module nommé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">jquery</span>.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:96px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// node_modules/@types/jquery/index.d.ts</span>
&nbsp;
<span style="color: #0000ff;">declare</span> <span style="color: #0000ff;font-weight:bold">module</span> <span style="color: #FF0000;">&quot;jquery&quot;</span> <span style="color: black;">&#123;</span>
    <span style="color: #0000ff;font-weight:bold">export</span> <span style="color: black;">=</span> $<span style="color: black;">;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
Contrairement au fichier de définition de types du module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">underscore</span>, <i>node_modules/@types/underscore/index.d.ts</i>, qui se contente d'exporter son espace de nommage sans l'emballer dans une déclaration de module. A noter qu'il ne faut pas se laisser abuser par le <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">declare module _</span> juste sous l'<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">export</span>. Il s'agit de l'ancienne syntaxe pour déclarer un espace de nommage qui employait également le mot-clé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">module</span>, mais qui désormais utilise <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">namespace</span>, ce dernier prêtant beaucoup moins à confusion.<br />
<br />
<b><font size="3">7.3. Fichier projet</font></b><br />
<br />
En tout cas, même si le module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">jquery</span> est localisé, nous devons indiquer à TypeScript où se trouve <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">underscore</span>. La solution la plus évidente serait d'ajouter dans l'appel à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">require</span>, un chemin d'accès devant le nom du module. Cependant, pour des raisons de maintenabilité, il est préférable de passer par une option du compilateur, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">--moduleResolution</span>, déjà évoquée plus haut, et qui avec la valeur <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">node</span>, permet au compilateur de rechercher les modules dans le répertoire <i>node_modules/</i>.<br />
<br />
Cette option est également disponible dans le fichier projet <i>tsconfig.json</i> comme ci-dessous :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td valign="top"><pre style="margin: 0">// tsconfig.json

{
    &quot;compilerOptions&quot;: {
        &quot;noImplicitAny&quot;: true,
        &quot;strictNullChecks&quot;: true,
        &quot;target&quot;: &quot;es5&quot;,
        &quot;module&quot;: &quot;amd&quot;,
        &quot;moduleResolution&quot;: &quot;node&quot;,
        &quot;allowJs&quot; : true,
        &quot;outDir&quot;: &quot;./build&quot;
    },
    &quot;exclude&quot; : [
        &quot;./build&quot;,
        &quot;./node_modules&quot;
    ]
}</pre></td></tr></table></pre>
</div>Avec ce nouveau paramétrage, le compilateur devrait cette fois-ci localiser le module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">underscore</span> (et le module <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">jquery</span>) comme il se doit.<br />
<br />
<b><font size="3">7.4. Fichier de configuration RequireJS</font></b><br />
<br />
Même si tout compile correctement, nous devons néanmoins penser à préciser le chemin d'accès à ces deux modules dans le fichier de configuration de RequireJS afin de permettre leur chargement au moment de l'exécution.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code typescript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// config.ts</span>
&nbsp;
<span style="color: #0000ff;">require</span>.<span style="color: #0080ff;">config</span><span style="color: black;">&#40;</span><span style="color: black;">&#123;</span>
    paths<span style="color: black;">:</span> <span style="color: black;">&#123;</span>
        jquery<span style="color: black;">:</span> <span style="color: #FF0000;">'../node_modules/jquery/dist/jquery'</span><span style="color: black;">,</span>
        underscore<span style="color: black;">:</span> <span style="color: #FF0000;">'../node_modules/underscore/underscore'</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
&nbsp;
<span style="color: #0000ff;">require</span><span style="color: black;">&#40;</span>
    <span style="color: black;">&#91;</span><span style="color: #FF0000;">'app'</span><span style="color: black;">&#93;</span><span style="color: black;">,</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">function</span> <span style="color: black;">&#40;</span>app<span style="color: black;">:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        app.<span style="color: #0080ff;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span><span style="color: black;">,</span>
&nbsp;
    <span style="color: #0000ff;font-weight:bold">function</span> <span style="color: black;">&#40;</span>err<span style="color: black;">:</span> <span style="color: #0080ff;">any</span><span style="color: black;">&#41;</span> <span style="color: black;">&#123;</span>
        console.<span style="color: #0080ff;">error</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'ERROR: '</span><span style="color: black;">,</span> err.<span style="color: #0080ff;">requireType</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
        console.<span style="color: #0080ff;">error</span><span style="color: black;">&#40;</span><span style="color: #FF0000;">'MODULES: '</span><span style="color: black;">,</span> err.<span style="color: #0080ff;">requireModules</span><span style="color: black;">&#41;</span><span style="color: black;">;</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#41;</span><span style="color: black;">;</span></pre></td></tr></table></pre>
</div><br />
<b><font size="3">7.5. Résultat de la compilation</font></b><br />
<br />
<b>Projet/<br />
<div style="margin-left:40px">build/<br />
<div style="margin-left:40px"><font color="#0000CD">app.js<br />
config.js</font></div>node_modules/<br />
<div style="margin-left:40px">@types/<br />
<div style="margin-left:40px">jquery/   <font color="#0000CD">...</font></div><div style="margin-left:40px">requirejs/   <font color="#0000CD">...</font></div><div style="margin-left:40px">underscore/   <font color="#0000CD">...</font></div></div><div style="margin-left:40px">jquery/   <font color="#0000CD">...</font></div><div style="margin-left:40px">requirejs/</div><div style="margin-left:40px"><div style="margin-left:40px"><font color="#0000CD">require.js</font></div><div style="margin-left:40px"><font color="#0000CD">...</font></div></div><div style="margin-left:40px">underscore/   <font color="#0000CD">...</font></div>script/<br />
<div style="margin-left:40px"><font color="#0000CD">app.ts<br />
config.ts</font></div><font color="#0000CD">index.html</font><br />
<font color="#0000CD">tsconfig.json</font></div></b><br />
<br />
<br />
<b><font size="3">8. Conclusion</font></b><br />
<br />
Dans cet article, nous avons pu voir différents cas d'importation de modules externes, écrits en TypeScript ou en JavaScript, avec des formes diverses. Cependant, tous les cas possibles n'ont évidemment pas été couverts, mais devrait donner une bonne base pour extrapoler l'importation de modules dans des situations plus ou moins proches.<br />
<br />
En espérant que cet article vous a été utile, n'hésitez pas à le partager.</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1533/importation-modules-externes-typescript/</guid>
		</item>
		<item>
			<title>Utiliser Visual Studio Code avec une version de TypeScript plus récente</title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b1535/utiliser-visual-studio-code-version-typescript-plus-recente/</link>
			<pubDate>Wed, 20 Jul 2016 08:27:04 GMT</pubDate>
			<description>Image :...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Visual_Studio_Code_0.10.1_icon.png/64px-Visual_Studio_Code_0.10.1_icon.png" border="0" alt="" /> <img src="http://www.developpez.net/forums/attachments/p156011d1410504996/webmasters-developpement-web-9/javascript-ajax-typescript-dart-2000/typescript-2001/typescript-annonce-nouveau-compilateur/logo-typescript.png/" border="0" alt="" /></div><br />
<br />
Comme cela a été <a href="http://www.developpez.net/forums/d1594916/webmasters-developpement-web/javascript-ajax-typescript-dart/typescript/typescript-2-0-disponible-beta/" target="_blank">publié sur le forum</a>, la version 2.0 de TypeScript est disponible en beta. Pour utiliser cette nouvelle version avec Visual Studio, un plugin adéquat a été mis à disposition par Microsoft. Cependant, pour ceux qui utilisent son petit frère qu'est <b><a href="https://code.visualstudio.com/download" target="_blank">Visual Studio Code</a></b>, ils peuvent se retrouver coincés avec la version 1.8 de TypeScript intégrée avec l'outil, en attendant la mise en production de TypeScript 2.0.<br />
<br />
Pour remédier à cela, il est possible de configurer la version de TypeScript qu'utilise Visual Studio Code. Il suffit de suivre les quelques étapes que voici.<br />
<br />
<b>1.</b> Si ce n'est pas déjà fait, téléchargez la version beta de TypeScript 2.0 via la commande suivante : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install -g typescript@beta</span>.<br />
Cela suppose évidemment d'avoir installé <b><a href="https://nodejs.org/en/download/" target="_blank">nodeJS</a></b> au préalable. Mais bon, difficile de faire sans de nos jours.<br />
<br />
A noter que pour installer la version <i>nightly</i>, encore plus expérimentale donc, c'est la commande suivante qu'il faut lancer : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">npm install -g typescript@next</span>.<br />
<br />
TypeScript devrait avoir été installé dans un répertoire de la forme <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">&lt;utilisateur&gt;/&lt;espace de travail&gt;/npm/node_modules/typescript/lib/</span>.<br />
<br />
Pour identifier le répertoire, vous pouvez toujours lancer la recherche du fichier <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">tsserver.js</span>, puisqu'il s'agit du fichier contenant l'API <i>Language Service</i> utilisé par Visual Studio Code pour tout ce qui est analyse syntaxique à la volée.<br />
<br />
<b>2.</b> Une fois le répertoire identifié, ouvrez Visual Studio Code, puis cliquez sur le menu Fichier/Préférences/Paramètres utilisateur. Un fichier settings.json devrait s'ouvrir. A l'intérieur de celui-ci, ajoutez la ligne suivante : <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">&quot;typescript.tsdk&quot;: &lt;utilisateur&gt;/&lt;espace de travail&gt;/npm/npm_modules/typescript/lib/</span>.<br />
A droite de la clé <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">typescript.tsdk</span>, il faut saisir le répertoire où se trouve la nouvelle version de TypeScript à prendre en compte par Visual Studio Code. Celui de l'étape précédente.<br />
<br />
<b>3.</b> Il ne vous reste plus qu'à sauvegarder et à relancer Visual Studio Code. En ouvrant un fichier <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">.ts</span>, vous devriez voir &quot;TypeScript 2.0.0&quot; tout en bas à droite, indiquant que la nouvelle version de TypeScript a bien été prise en compte.<br />
<br />
Bon développement !</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b1535/utiliser-visual-studio-code-version-typescript-plus-recente/</guid>
		</item>
		<item>
			<title><![CDATA[JavaScript et le futur de l'asynchrone]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b795/javascript-futur-l-asynchrone/</link>
			<pubDate>Fri, 09 Oct 2015 09:20:27 GMT</pubDate>
			<description>Image :...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore"><div style="text-align: center;"><img src="http://www.developpez.net/forums/attachment.php?attachmentid=216664&amp;d=1469722811" border="0" alt="" /></div><br />
<font size="3"><i>Ce qui suit est une traduction d'un <a href="https://www.eternalcoding.com/?p=1942" target="_blank">article</a> du blog de David Catuhe (Microsoft) que je remercie pour avoir donné aimablement son accord</i></font><br />
<br />
JavaScript en a fait du chemin depuis ses premières versions, et grâce à tous les efforts réalisés par le TC39 (L'organisation en charge de la standardisation de JavaScript, ou ECMAScript pour être exact), nous avons maintenant un langage moderne qui est largement utilisé.<br />
<br />
Une des parties d'ECMAScript qui a reçu de grandes améliorations est la <b>programmation asynchrone</b>. Vous pouvez en apprendre plus sur la <a href="https://msdn.microsoft.com/en-us/library/hh191443.aspx" target="_blank">programmation asynchrone ici</a> si vous êtes un nouveau développeur. Heureusement, nous avons inclus ces changements dans le nouveau navigateur Edge de Windows 10. Consultez le journal des modifications ci-dessous : <br />
<br />
<a href="https://dev.modern.ie/platform/changelog/desktop/10547/" target="_blank">https://dev.modern.ie/platform/changelog/desktop/10547/</a><br />
<br />
Parmi toutes ces nouvelles fonctionnalités, nous allons nous concentrer en particulier sur les &quot;Fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span> ES2016&quot; (ES2016 Async Functions), effectuer un voyage à travers ces mises à jour et voir comment ECMAScript peut améliorer votre travail au quotidien dès aujourd'hui.<br />
<br />
<font size="4"><b>Première étape : ECMAScript 5 - Callback City</b></font><br />
<br />
ECMAScript 5 (et les versions antérieures) ne jurent que par les <i>callbacks</i> (fonctions auxiliaires). Pour illustrer ceci, prenons un exemple simple que vous utilisez certainement plus d'une fois par jour : l'exécution d'une requête XHR.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">var</span> displayDiv = <span style="color: #0080ff;">document</span>.<span style="color: #0080ff;">getElementById</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;displayDiv&quot;</span><span class="br0">&#41;</span>;
&nbsp;
<span style="color: #808080;">// Part 1 - Defining what do we want to do with the result</span>
<span style="color: #0000ff;">var</span> processJSON = <span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>json<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0000ff;">var</span> result = <span style="color: #0080ff;">JSON</span>.<span style="color: #0080ff;">parse</span><span class="br0">&#40;</span>json<span class="br0">&#41;</span>;
&nbsp;
    result.collection.<span style="color: #0080ff;">forEach</span><span class="br0">&#40;</span><span style="color: #0000ff;">function</span><span class="br0">&#40;</span>card<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">var</span> div = <span style="color: #0080ff;">document</span>.<span style="color: #0080ff;">createElement</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;div&quot;</span><span class="br0">&#41;</span>;
        div.innerHTML = card.<span style="color: #0080ff;">name</span> + <span style="color: #FF0000;">&quot; cost is &quot;</span> + card.price;
&nbsp;
        displayDiv.<span style="color: #0080ff;">appendChild</span><span class="br0">&#40;</span>div<span class="br0">&#41;</span>;
    <span class="br0">&#125;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #808080;">// Part 2 - Providing a function to display errors</span>
<span style="color: #0000ff;">var</span> displayError = <span style="color: #0000ff;">function</span><span class="br0">&#40;</span>error<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    displayDiv.innerHTML = error;
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #808080;">// Part 3 - Creating and setting up the XHR object</span>
<span style="color: #0000ff;">var</span> xhr = <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">XMLHttpRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
xhr.<span style="color: #0080ff;">open</span><span class="br0">&#40;</span><span style="color: #FF0000;">'GET'</span>, <span style="color: #FF0000;">&quot;cards.json&quot;</span><span class="br0">&#41;</span>;
&nbsp;
<span style="color: #808080;">// Part 4 - Defining callbacks that XHR object will call for us</span>
xhr.<span style="color: #0080ff;">onload</span> = <span style="color: #0000ff;">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>
    <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>xhr.<span style="color: #0080ff;">status</span> === <span style="color: #cc66cc;">200</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0080ff;">processJSON</span><span class="br0">&#40;</span>xhr.response<span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
xhr.<span style="color: #0080ff;">onerror</span> = <span style="color: #0000ff;">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0080ff;">displayError</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Unable to load RSS&quot;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #808080;">// Part 5 - Starting the process</span>
xhr.<span style="color: #0080ff;">send</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
Les développeurs JavaScript chevronnés noteront à quel point cela leur semble familier puisque les <i>callbacks</i> pour XHR sont utilisées tout le temps ! C'est simple et relativement direct : le développeur crée une requête XHR, puis fournit le <i>callback</i> de l'objet XHR spécifié.<br />
<br />
En revanche, la complexité du <i>callback</i> vient de l'ordre d'exécution qui est non linéaire en raison de la nature intrinsèque de la programmation asynchrone :<br />
<br />
<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/8816.image_thumb_35C48EA5.png" border="0" alt="" /><br />
<br />
&quot;<a href="http://callbackhell.com/" target="_blank">L'Enfer des callbacks</a>&quot; peut même être pire lorsque vous utilisez un autre appel asynchrone au sein de votre propre <i>callback</i>.<br />
<br />
<font size="4"><b>Seconde étape : ECMAScript 6 – Promises City</b></font><br />
<br />
ECMAScript 6 est sur une bonne dynamique d'adoption où <a href="http://kangax.github.io/compat-table/es6/" target="_blank">Edge détient le meilleur score</a> avec 88% (en mode expérimental).<br />
<br />
Parmi de nombreuses améliorations d'importances, ECMAScript 6 standardise l'utilisation des <i>promises</i> (anciennement connues sous le nom de <i>futures</i>).<br />
<br />
Selon <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" target="_blank">MDN</a>, une <i>promise</i> est un objet qui est utilisé pour les opérations déportées (<i>deferred</i>) et asynchrones. Une <i>promise</i> représente une opération qui ne s'est pas encore terminée, mais qui est prévue de l'être à l'avenir. Les <i>promises</i> sont une façon d'organiser les opérations asynchrones de façon à ce qu'elles apparaissent synchrones dans le code. Exactement ce dont nous avons besoin pour notre exemple avec XHR.<br />
<br />
<div style="text-align: left;">Les <i>promises</i> existent depuis un certain temps, mais la bonne nouvelle est que maintenant vous n'avez plus à utiliser une bibliothèque JavaScript puisqu'elles sont fournies dans le navigateur.</div><br />
Mettons légèrement à jour notre exemple précédent pour utiliser les <i>promises</i> et voyons comment cela améliore la lisibilité et la maintenabilité de notre code :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">var</span> displayDiv = <span style="color: #0080ff;">document</span>.<span style="color: #0080ff;">getElementById</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;displayDiv&quot;</span><span class="br0">&#41;</span>;
&nbsp;
<span style="color: #808080;">// Part 1 - Create a function that returns a promise</span>
<span style="color: #0000ff;">function</span> <span style="color: #0080ff;">getJsonAsync</span><span class="br0">&#40;</span>url<span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #808080;">// Promises require two functions: one for success, one for failure</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">Promise</span><span class="br0">&#40;</span><span style="color: #0000ff;">function</span> <span class="br0">&#40;</span>resolve, reject<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        <span style="color: #0000ff;">var</span> xhr = <span style="color: #0000ff;">new</span> <span style="color: #0080ff;">XMLHttpRequest</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
        xhr.<span style="color: #0080ff;">open</span><span class="br0">&#40;</span><span style="color: #FF0000;">'GET'</span>, url<span class="br0">&#41;</span>;
&nbsp;
        xhr.<span style="color: #0080ff;">onload</span> = <span class="br0">&#40;</span><span class="br0">&#41;</span> =&gt; <span class="br0">&#123;</span>
            <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>xhr.<span style="color: #0080ff;">status</span> === <span style="color: #cc66cc;">200</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span style="color: #808080;">// We can resolve the promise</span>
                <span style="color: #0080ff;">resolve</span><span class="br0">&#40;</span>xhr.response<span class="br0">&#41;</span>;
            <span class="br0">&#125;</span> <span style="color: #0000ff;">else</span> <span class="br0">&#123;</span>
                <span style="color: #808080;">// It's a failure, so let's reject the promise</span>
                <span style="color: #0080ff;">reject</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Unable to load RSS&quot;</span><span class="br0">&#41;</span>;
            <span class="br0">&#125;</span>
        <span class="br0">&#125;</span>
&nbsp;
        xhr.<span style="color: #0080ff;">onerror</span> = <span class="br0">&#40;</span><span class="br0">&#41;</span> =&gt; <span class="br0">&#123;</span>
            <span style="color: #808080;">// It's a failure, so let's reject the promise</span>
            <span style="color: #0080ff;">reject</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Unable to load RSS&quot;</span><span class="br0">&#41;</span>;
        <span class="br0">&#125;</span>;
&nbsp;
        xhr.<span style="color: #0080ff;">send</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #808080;">// Part 2 - The function returns a promise</span>
<span style="color: #808080;">// so we can chain with a .then and a .catch</span>
<span style="color: #0080ff;">getJsonAsync</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;cards.json&quot;</span><span class="br0">&#41;</span>.<span style="color: #0080ff;">then</span><span class="br0">&#40;</span>json =&gt; <span class="br0">&#123;</span>
    <span style="color: #0000ff;">var</span> result = <span style="color: #0080ff;">JSON</span>.<span style="color: #0080ff;">parse</span><span class="br0">&#40;</span>json<span class="br0">&#41;</span>;
&nbsp;
    result.collection.<span style="color: #0080ff;">forEach</span><span class="br0">&#40;</span>card =&gt; <span class="br0">&#123;</span>
        <span style="color: #0000ff;">var</span> div = <span style="color: #0080ff;">document</span>.<span style="color: #0080ff;">createElement</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;div&quot;</span><span class="br0">&#41;</span>;
        div.innerHTML = <span style="color: #FF0000;">`<span style="color: #800000;">${card.name}</span> cost is <span style="color: #800000;">${card.price}</span>`</span>;
&nbsp;
        displayDiv.<span style="color: #0080ff;">appendChild</span><span class="br0">&#40;</span>div<span class="br0">&#41;</span>;
    <span class="br0">&#125;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span><span class="br0">&#41;</span>.<span style="color: #0000ff;">catch</span><span class="br0">&#40;</span>error =&gt; <span class="br0">&#123;</span>
    displayDiv.innerHTML = error;
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
Ci-dessus, vous avez peut-être remarqué beaucoup d'améliorations. Regardons de façon plus attentive.<br />
<br />
<font size="3"><b>Création de la <i>promise</i></b></font><br />
<br />
Afin de &quot;promisifier&quot; (désolé pour le néologisme) l'ancien objet XHR, vous devez créer un objet <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">Promise</span> :<br />
<br />
<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/6305.image_thumb_56493DA6.pngg" border="0" alt="" /><br />
<br />
<font size="3"><b>Utilisation de la <i>promise</i></b></font><br />
<br />
Une fois créée, la <i>promise</i> peut être utilisée pour enchaîner les appels asynchrones de manière plus élégante :<br />
<br />
<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/6012.image_thumb_0D8FC4E2.png" border="0" alt="" /><br />
<br />
Nous avons donc maintenant (du point de vue de l'utilisateur) :<br />
<ul><li style="">Récupéré la <i>promise</i> (1)</li><li style="">Enchaîné avec le code de succès (2 et 3)</li><li style="">Enchaîné avec le code d'erreur (4) comme dans un bloc <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">try</span>/<span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">catch</span></li></ul><br />
<br />
Ce qui est intéressant est que les <i>promises</i> chaînées sont facilement appelables à l'aide de <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">.then().then()</span>, etc.<br />
<br />
<div style="text-align: left;">Remarque : Puisque JavaScript est un langage moderne, vous remarquerez peut-être que j'utilise aussi le <a href="https://en.wikipedia.org/wiki/Syntactic_sugar" target="_blank">sucre syntaxique</a> d'ECMAScript 6 comme l'<a href="http://tc39wiki.calculist.org/es6/template-strings/" target="_blank">interpolation de chaînes</a> ou la <a href="http://tc39wiki.calculist.org/es6/arrow-functions/" target="_blank">notation fléchée</a> (<i>arrow function</i>).</div><br />
<font size="4"><b>Terminus : ECMAScript 7 – Asynchronous city</b></font><br />
<br />
Enfin, nous avons atteint notre destination ! Nous sommes presque dans le futur, mais grâce au cycle de développement rapide d'Edge, l'équipe est en mesure d'introduire un peu d'ECMAScript 7 avec des fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span> dans la dernière version !<br />
<br />
Les functions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span> sont un sucre syntaxique pour améliorer le modèle au niveau du langage dans le but d'écrire du code asynchrone.<br />
<br />
Les fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span> sont construites par dessus les fonctionnalités d'ECMAScript 6 comme les générateurs. En effet, les générateurs peuvent être utilisées conjointement avec des <i>promises</i> pour produire les mêmes résultats, mais avec beaucoup plus de code d'utilisateur.<br />
<br />
On n'a pas besoin de changer la fonction qui génère la <i>promise</i> dans la mesure où les fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span> travaillent directement avec la <i>promise</i>.<br />
<br />
Nous avons seulement besoin de changer la fonction d'appel :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code javascript :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #808080;">// Let's create an async anonymous function</span>
<span class="br0">&#40;</span><span style="color: #0000ff;">async</span> <span style="color: #0000ff;">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span style="color: #0000ff;">try</span> <span class="br0">&#123;</span>
        <span style="color: #808080;">// Just have to await the promise!</span>
        <span style="color: #0000ff;">var</span> json = <span style="color: #0000ff;">await</span> <span style="color: #0080ff;">getJsonAsync</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;cards.json&quot;</span><span class="br0">&#41;</span>;
        <span style="color: #0000ff;">var</span> result = <span style="color: #0080ff;">JSON</span>.<span style="color: #0080ff;">parse</span><span class="br0">&#40;</span>json<span class="br0">&#41;</span>;
&nbsp;
        result.collection.<span style="color: #0080ff;">forEach</span><span class="br0">&#40;</span>card =&gt; <span class="br0">&#123;</span>
            <span style="color: #0000ff;">var</span> div = <span style="color: #0080ff;">document</span>.<span style="color: #0080ff;">createElement</span><span class="br0">&#40;</span><span style="color: #FF0000;">&quot;div&quot;</span><span class="br0">&#41;</span>;
            div.innerHTML = <span style="color: #FF0000;">`<span style="color: #800000;">${card.name}</span> cost is <span style="color: #800000;">${card.price}</span>`</span>;
&nbsp;
            displayDiv.<span style="color: #0080ff;">appendChild</span><span class="br0">&#40;</span>div<span class="br0">&#41;</span>;
        <span class="br0">&#125;</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span> <span style="color: #0000ff;">catch</span> <span class="br0">&#40;</span>e<span class="br0">&#41;</span> <span class="br0">&#123;</span>
        displayDiv.innerHTML = e;
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div><br />
C'est ici que la magie intervient. Ce code ressemble à du code synchrone normal avec une exécution parfaitement linéaire :<br />
<br />
<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/1665.image_thumb_0BBF6F1B.png" border="0" alt="" /><br />
<br />
Plutôt impressionnant, n'est-ce pas ?<br />
<br />
Et la bonne nouvelle est que vous pouvez même utiliser les fonctions <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">async</span> avec la notation fléchée ou les méthodes de classe.<br />
<br />
<font size="3"><b>Pour aller plus loin</b></font><br />
<br />
Si vous voulez plus de détails sur la façon dont nous avons implémenté Chakra, vous pouvez vous rendre sur le message officiel du blog de Edge :<br />
<br />
<a href="http://blogs.windows.com/msedgedev/2015/09/30/asynchronous-code-gets-easier-with-es2016-async-function-support-in-chakra-and-microsoft-edge/" target="_blank">http://blogs.windows.com/msedgedev/2...icrosoft-edge/</a><br />
<br />
Vous pouvez également suivre la progression de l'implémentation d'ECMAScript 6 et 7 dans les différents navigateurs en utilisant le <a href="http://kangax.github.io/compat-table/es6/" target="_blank">site Web de Kangax</a> : N'hésitez pas également à jeter un oeil sur notre <a href="https://dev.modern.ie/platform/status/javascript/" target="_blank">feuille de route JavaScript</a> !<br />
<br />
S'il vous plaît, n'hésitez pas à nous donner un retour et à soutenir vos fonctions préférées en utilisant le bouton de vote :<br />
<br />
<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/44/73/metablogapi/1348.image_thumb_49FA5F60.png" border="0" alt="" /><br />
<br />
Merci d'avoir lu et nous sommes impatients d'entendre vos commentaires et vos idées !<br />
<br />
David Catuhe <br />
Principal Program Manager <br />
<a href="http://www.twitter.com/deltakosh" target="_blank">@deltakosh</a></blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b795/javascript-futur-l-asynchrone/</guid>
		</item>
		<item>
			<title><![CDATA[[JS] Interpréter du JavaScript en JavaScript, ce n'est pas si simple ! (Partie 2)]]></title>
			<link>https://www.developpez.net/forums/blogs/676693-yahiko/b465/js-interpreter-javascript-javascript-n-simple-partie-2/</link>
			<pubDate>Sun, 26 Apr 2015 20:36:09 GMT</pubDate>
			<description>Lors de mon *précédent billet...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">Lors de mon <b><a href="http://www.developpez.net/forums/blogs/676693-yahiko/b433/js-interpreter-javascript-javascript-n-simple-partie-1/" target="_blank">précédent billet</a></b>, j'avais présenté la fonction <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">eval()</span> et montré en quoi il était peu recommandé de l’utiliser.<br />
<br />
Je vais montrer dans ce billet un moyen d’interpréter du code JavaScript sans utiliser <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">eval()</span>, mais avant cela, essayons de voir les cas d'utilisation où l'interprétation de scripts peut s'avérer nécessaire.<br />
<br />
Faire appel à des scripts au sein d'une application n'est pas nécessairement un besoin très courant dans la mise en œuvre d'un site web ou même de la plupart des applications que l'on peut rencontrer sur la toile.<br />
<br />
Cependant, cela peut s'avérer utile voire nécessaire lorsqu'interviennent des règles pouvant être ajoutées (ou retirées) à postériori de la phase de développement, où lorsque tout simplement il est plus simple ou plus rapide d'implémenter ces règles à travers des scripts plutôt qu'en travaillant sur l'application en elle-même.<br />
<br />
Le cas le plus typique et le plus parlant est probablement le jeu vidéo, où il est très fréquent de faire appel à du scripting pour gérer soit des règles très spécifiques et pointues comme l'intelligence artificielle qui font souvent appel à un/des développeur/s dédié/s, ou pour faciliter les développements en fournissant aux développeurs un moyen plus simple d'étendre les fonctionnalités du jeu sans avoir à modifier (et donc à re-tester) le cœur du programme.<br />
<br />
Les jeux développés en langage C ou C++ font assez régulièrement appel au langage Lua pour le scripting, plus pour des raisons d'habitudes que pour les qualités intrinsèques de Lua disons-le. Mais avec l'avènement du HTML5 et des jeux online, le choix d'utiliser JavaScript comme langage de scripting, d'autant plus qu'il devient de plus en plus populaire côté serveur avec node.js, est tout à fait envisageable, à condition de pouvoir interpréter du code JavaScript de façon fiable, donc sans faire appel à la primitive <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">eval()</span>.<br />
<br />
On cherche en fait à pouvoir interpréter du code JavaScript dans une sorte d'environnement protégé, on parle souvent de <i>sandboxing</i> (bac à sable) à ce propos.<br />
<br />
Pour cela, le seul moyen n'est ni plus ni moins d'employer un interpréteur JavaScript externe qui nous permettra de lancer des scripts qui n'auront pas accès aux variables globales du programme appelant.<br />
<br />
On ne veut donc surtout pas ici que l'interprétation se comporte comme une fermeture (<i>closure</i>), comme c'est le cas de la primitive <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">eval()</span> en mode strict comme vu dans la partie précédente.<br />
<br />
Il existe assez peu d'interpréteurs JavaScript implémentés eux-même en JavaScript. Il faut croire que la technologie HTML5 doit encore faire ses preuves dans le domaine vidéo-ludique, mais c'est un autre sujet.<br />
<br />
On peut trouver actuellement trois interpréteurs JavaScript open source écrits en JavaScript :<br />
<ul><li style=""><a href="https://github.com/NeilFraser/JS-Interpreter" target="_blank"><b>JS Interpreter</b></a></li><li style=""><a href="https://github.com/mozilla/narcissus" target="_blank"><b>Narcissus</b></a></li><li style=""><a href="https://github.com/Benvie/continuum" target="_blank"><b>Continuum</b></a></li></ul><br />
<br />
L'interpréteur le plus simple à appréhender des trois est le premier, JS Interpreter, réalisé par un développeur de chez Google, bien que le projet ne soit pas officiellement un projet Google.<br />
<br />
Son utilisation est relativement directe comme le montre l'exemple ci-dessous :<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:84px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br /></div></td><td valign="top"><pre style="margin: 0">var myCode = 'var a=1; for(var i=0;i&lt;4;i++){a*=i;} a;';
var myInterpreter = new Interpreter(myCode);
myInterpreter.run();
var result = myInterpreter.value;</pre></td></tr></table></pre>
</div>Le code JavaScript interprété est ainsi totalement isolé du programme appelant et ne peut pas par exemple modifier des variables globales du programme appelant contrairement à <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">eval()</span>.<br />
<br />
Cependant, il peut être utile et même nécessaire de rendre accessible, d'exposer, certaines variables ou fonctions du programme appelant au script interprété.<br />
<br />
JS Interpreter le permet à l'aide d'un paramètre optionnel, une fonction d'initialisation du contexte, à passer au constructeur de l'interpréteur.<br />
<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code  :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:180px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td valign="top"><pre style="margin: 0">function square(x) {
    return x * x;
}

var initFunc = function(interpreter, scope) {
    var wrapper = function(x) {
        return interpreter.createPrimitive(square(x));
    };
    interpreter.setProperty(scope, 'square', interpreter.createNativeFunction(wrapper));
};

var myInterpreter = new Interpreter('var y = square(5)', initFunc);</pre></td></tr></table></pre>
</div>Ainsi, nous avons à la fois un environnement JavaScript isolé du programme appelant, tout en ayant la possibilité d'exposer explicitement certaines fonctions, <span style="font-family: monospace; padding: 2px; background: #ddd; display: inline-block">square()</span> dans l'exemple ci-dessus, du programme appelant dans le script.<br />
<br />
Nous pouvons donc définir dans le programme appelant un ensemble de fonctions accessible aux scripts formant de la sorte ce qui est commun d'appeler une API de scripting.<br />
<br />
A noter tout de même, en bémol, que l'interpréteur JS Interpreter, en l'état, est très basique. Il vous faudra sans doute le modifier et l'adapter pour qu'il puisse être utilisé dans le cadre d'un véritable environnement de scripting, mais c'est déjà un bon début.<br />
<br />
Les deux autres interpréteurs JavaScript mentionnés plus haut manquent quand à eux d'une documentation claire et complète pour en saisir facilement toutes les fonctionnalités. Ce qui est assez dommage.<br />
<br />
Enfin, il est à regretter que ces trois projets ne semblent plus être réellement maintenus au moment où j'écris ces lignes.<br />
<br />
A l'heure où le développement de jeux Web utilisant la technologie HTML5 devient de plus en plus répandu, il reste surprenant qu'il y ait un tel déficit au niveau des interpréteurs JavaScript écrits en JavaScript.<br />
<br />
Il pourrait être judicieux par conséquent, c'est une réflexion en cours pour ma part, de forker le projet JS Interpreter pour développer ses fonctionnalités, avec notamment le support de la norme ECMAScript 5 à minima voire d'ECMAScript 6 idéalement.<br />
<br />
A ceux que ce projet pourrait intéresser, qu'ils n'hésitent pas à me contacter en message privé.</blockquote>

]]></content:encoded>
			<dc:creator>yahiko</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/676693-yahiko/b465/js-interpreter-javascript-javascript-n-simple-partie-2/</guid>
		</item>
	</channel>
</rss>
