Les plats clés
- La programmation réactive est une méthode de programmation avec des flux de données simultanés, qui peuvent être asynchrones. Il peut être appliqué aux problèmes de programmation car un processeur traite un flux d'informations composé d'instructions et de données.
- La bibliothèque réactive pour la bibliothèque JavaScript (RXJS) utilise le chaînage de méthode et présente des observables (producteurs) et des observateurs (consommateurs). Les deux types d'observables sont des observables chauds, qui poussent même lorsqu'ils ne sont pas abonnés, et les observables à froid, qui commencent à pousser uniquement lorsqu'ils sont abonnés.
- Les observables peuvent être créés à partir de tableaux, de promesses, de fonctions et de générateurs, et peuvent être utilisés pour fournir plusieurs valeurs de retour asynchrones. Les observables poussent les valeurs et ne peuvent pas forcer l'événement suivant.
- RXJS fournit de nombreux opérateurs qui introduisent la concurrence, tels que l'accélérateur, l'intervalle ou le retard. Ceux-ci peuvent être utilisés pour agréger les événements sur un intervalle de temps spécifié, ou pour accélérer l'entrée pour démarrer uniquement les demandes après un certain temps d'inactivité.
- RXJS rend la programmation réactive dans JavaScript plus facile et plus efficace. Il unifie certains des concepts de programmation réactive dans un ensemble de méthodes concises et composables. Il a également des extensions utiles, telles que RxJS-DOM, ce qui simplifie l'interaction avec le dom.
Cet article a été révisé par des pairs par Moritz Kröger, Bruno Mota et Vildan Softic. Merci à tous les pairs examinateurs de SitePoint pour avoir fait du contenu SitePoint le meilleur possible!
Avant de plonger dans le sujet, nous devons répondre à la question cruciale: qu'est-ce que la programmation réactive? À ce jour, la réponse la plus populaire est que la programmation réactive est la programmation avec des flux de données simultanés. La plupart du temps, nous trouverons le mot simultanément remplacé par des asynchrones, cependant, nous verrons plus tard que le flux n'a pas besoin d'être asynchrone.
Il est facile de voir que l'approche «tout est un flux» peut être appliquée directement à nos problèmes de programmation. Après tout, un CPU n'est rien de plus qu'un appareil qui traite un flux d'informations composé d'instructions et de données. Notre objectif est d'observer ce flux et de le transformer en cas de données particulières.
Les principes de la programmation réactive ne sont pas complètement nouveaux pour JavaScript. Nous avons déjà des choses comme la liaison des propriétés, le modèle EventEmitter ou les flux Node.js. Parfois, l'élégance de ces méthodes s'accompagne d'une diminution des performances, des abstractions trop compliquées ou des problèmes de débogage. Habituellement, ces inconvénients sont minimes par rapport aux avantages de la nouvelle couche d'abstraction. Nos exemples minimaux ne refléteront bien sûr pas l'application habituelle, mais seront aussi courtes et concises que possible.
Sans plus tarder, salissons nos mains en jouant avec la bibliothèque réactive des extensions pour JavaScript (RXJS). RXJS utilise beaucoup de choutage, qui est une technique populaire également utilisée dans d'autres bibliothèques telles que jQuery. Un guide du chaînage de méthodes (dans le contexte de Ruby) est disponible sur SitePoint.
Exemples de flux
Avant de plonger dans RXJS, nous devons énumérer quelques exemples pour travailler plus tard. Cela conclura également l'introduction à la programmation réactive et aux flux en général.
En général, nous pouvons distinguer deux types de flux: internes et externes. Alors que le premier peut être considéré comme artificiel et sous notre contrôle, les seconds proviennent de sources indépendantes de notre volonté. Les flux externes peuvent être déclenchés (directement ou indirectement) à partir de notre code.
Habituellement, les flux ne nous attendent pas. Ils se produisent, que nous puissions les gérer ou non. Par exemple, si nous voulons observer les voitures sur une route, nous ne pourrons pas redémarrer le flux de voitures. Le flux se déroule indépendamment de si nous l'observons ou non. Dans la terminologie RX, nous appelons cela un Hot observable . Rx introduit également observables à froid , qui se comportent plus comme des itérateurs standard, de sorte que les informations du flux se compose de tous les éléments pour chaque observateur.
Les images suivantes illustre certains types de flux externes. Nous voyons que les demandes (anciennement démarrées) et la configuration généralement des crochets Web sont mentionnées, ainsi que des événements d'interface utilisateur tels que les interactions de souris ou de clavier. Enfin, nous pouvons également recevoir des données de périphériques, par exemple des capteurs GPS, un accéléromètre ou d'autres capteurs.
L'image contenait également un flux noté comme messages . Les messages peuvent apparaître sous plusieurs formes. L'une des formes les plus simples est une communication entre notre site Web et un autre site Web. D'autres exemples incluent la communication avec les lignes Web ou les travailleurs du Web. Voyons un exemple de code pour ce dernier.
Le code du travailleur est présenté ci-dessous. Le code essaie de trouver les nombres premiers de 2 à 10 10 . Une fois un nombre trouvé, le résultat est rapporté.
<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span></span></span>
Classiquement, le travailleur Web (supposé être dans le fichier prime.js) est inclus comme suit. Pour Brivity, nous ignorons les chèques pour le soutien des travailleurs Web et la légalité du résultat retourné.
<span>var worker = new Worker('prime.js'); </span>worker<span>.addEventListener('message', function (ev) { </span> <span>var primeNumber = ev.data * 1; </span> <span>console.log(primeNumber); </span><span>}, false); </span>
Plus de détails sur les travailleurs Web et le multi-threads avec JavaScript se trouvent dans l'article parallèle JavaScript avec parallel.js.
Compte tenu de l'exemple ci-dessus, nous savons que les nombres premiers suivent une distribution asymptotique entre les entiers positifs. Pour x à ∞, nous obtenons une distribution de x / log (x). Cela signifie que nous verrons plus de chiffres au début. Ici, les chèques sont également beaucoup moins chers (c'est-à-dire que nous recevons beaucoup plus de nombres premiers par unité de temps au début que plus tard.)
Cela peut être illustré avec un axe temporel simple et des blobs pour les résultats:
Un exemple non lié mais similaire peut être donné en examinant l'entrée d'un utilisateur dans une zone de recherche. Initialement, l'utilisateur peut être enthousiaste à la recherche de quelque chose à rechercher; Cependant, plus sa demande est spécifique, plus la différence de temps entre les traits clés devient grande. Fournir la possibilité de montrer des résultats en direct est certainement souhaitable, pour aider l'utilisateur à réduire sa demande. Cependant, ce que nous ne voulons pas, c'est effectuer une demande pour chaque accident vasculaire cérébral de clé, d'autant plus que les premiers seront effectués très rapidement et sans réfléchir ou la nécessité de se spécialiser.
Dans les deux scénarios, la réponse est d'agréger les événements précédents sur un intervalle de temps donné. Une différence entre les deux scénarios décrits est que les nombres premiers doivent toujours être affichés après l'intervalle de temps donné (c'est-à-dire que certains des nombres premiers sont tout simplement retardés dans la présentation). En revanche, la requête de recherche ne déclencherait une nouvelle demande que si aucune course de clé ne se produisait pendant l'intervalle spécifié. Par conséquent, la minuterie est réinitialisée une fois qu'un coup de clé a été détecté.
rxjs à la rescousse
RX est une bibliothèque pour composer des programmes asynchrones et basés sur des événements utilisant des collections observables. Il est bien connu pour sa syntaxe déclarative et sa composabilité tout en introduisant un modèle de gestion de temps et d'erreur facile. En pensant à nos anciens exemples, nous sommes particulièrement intéressés par la gestion du temps. Néanmoins, nous verrons qu'il y a beaucoup plus dans les RXJ pour bénéficier.
Les éléments constitutifs de base des RXJ sont des observables (producteurs) et des observateurs (consommateurs). Nous avons déjà mentionné les deux types d'observables:
- Les observables chauds poussent même lorsque nous ne les sommes pas abonnés (par exemple, les événements d'interface utilisateur).
- Les observables froids commencent à pousser uniquement lorsque nous souscrivons. Ils recommencent si nous abons à nouveau.
Les observables à froid se réfèrent généralement à des tableaux ou à des valeurs uniques qui ont été converties pour être utilisées dans RXJS. Par exemple, le code suivant crée un froid observable qui ne donne qu'une seule valeur avant de terminer:
<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span></span></span>
Nous pouvons également renvoyer une fonction contenant une logique de nettoyage à partir de la fonction de création observable.
L'abonnement à l'observable est indépendant du type d'observable. Pour les deux types, nous pouvons fournir trois fonctions qui remplissent l'exigence de base de la grammaire de notification composée de OnNext, ONERROR et ONCOMPLETED. Le rappel OnNext est obligatoire.
<span>var worker = new Worker('prime.js'); </span>worker<span>.addEventListener('message', function (ev) { </span> <span>var primeNumber = ev.data * 1; </span> <span>console.log(primeNumber); </span><span>}, false); </span>
En tant que meilleure pratique, nous devons mettre fin à l'abonnement en utilisant la méthode Disser. Cela effectuera toutes les étapes de nettoyage requises. Sinon, il pourrait être possible d'empêcher la collecte des ordures de nettoyer les ressources inutilisées.
sans souscrire, l'observable contenu dans la variable observable est juste un froid observable. Néanmoins, il est également possible de le convertir en une séquence chaude (c'est-à-dire que nous effectuons un abonnement pseudo) en utilisant la méthode de publication.
<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span></span></span>
Certains des aides contenus dans les RXJ ne traitent que la conversion des structures de données existantes. En JavaScript, nous pouvons distinguer trois d'entre eux:
- promet de retourner des résultats asynchrones uniques,
- Fonctions pour les résultats uniques, et
- générateurs pour fournir des itérateurs.
Ce dernier est nouveau avec ES6 et peut être remplacé par des tableaux (même si c'est un mauvais substitut et doit être traité comme une seule valeur) par ES5 ou plus.
RXJS apporte désormais un type de données pour fournir la prise en charge de la valeur multiple (retour) asynchrone. Par conséquent, les quatre quadrants sont maintenant remplis.
Alors que les itérateurs doivent être tirés, les valeurs des observables sont poussées. Un exemple serait un flux d'événements, où nous ne pouvons pas forcer le prochain événement à se produire. Nous ne pouvons attendre que d'être averti par la boucle d'événement.
<span>var worker = new Worker('prime.js'); </span>worker<span>.addEventListener('message', function (ev) { </span> <span>var primeNumber = ev.data * 1; </span> <span>console.log(primeNumber); </span><span>}, false); </span>
La plupart des aides créant ou traitant des observables acceptent également un planificateur, qui contrôle le début d'un abonnement et lorsque les notifications sont publiées. Nous n'entrerons pas dans les détails ici car le planificateur par défaut fonctionne très bien à la plupart des fins pratiques.
De nombreux opérateurs dans les RXJ introduisent la concurrence, tels que l'accélérateur, l'intervalle ou le retard. Nous allons maintenant examiner les exemples précédents, où ces aides deviennent essentiels.
Exemples
Tout d'abord, jetons un coup d'œil à notre générateur de nombres premiers. Nous voulions agréger les résultats au cours d'un temps donné, de sorte que l'interface utilisateur (en particulier au début) n'a pas à faire face à trop de mises à jour.
Ici, nous pourrions en fait vouloir utiliser la fonction tampon de RXJS en conjonction avec l'assistant d'intervalle mentionné précédemment.
Le résultat doit être représenté par le diagramme suivant. Les blobs verts surviennent après un intervalle de temps spécifié (donné par le temps utilisé pour construire l'intervalle). Un tampon agrégera tous les blobs bleus vus pendant un tel intervalle.
De plus, nous pourrions également introduire la carte, ce qui nous aide à transformer les données. Par exemple, nous pouvons vouloir transformer les arguments d'événement reçus pour obtenir les données transmises en nombre.
<span>var observable = Rx.<span>Observable</span>.create(function (observer) { </span> observer<span>.onNext(42); </span> observer<span>.onCompleted(); </span><span>}); </span>
La fonction Fromevent construit un observable à partir de tout objet utilisant le modèle d'émetteur d'événement standard. Le tampon renverrait également des tableaux avec une longueur zéro, c'est pourquoi nous introduisons la fonction où réduire le flux en tableaux non vides. Enfin, dans cet exemple, nous ne sommes intéressés que par le nombre de nombres premiers générés. Par conséquent, nous mapperons le tampon pour obtenir sa longueur.
L'autre exemple est la zone de requête de recherche, qui doit être étranglée pour démarrer les demandes qu'après un certain temps inactive. Il existe deux fonctions qui peuvent être utiles dans un tel scénario: la fonction de gaz donne la première entrée vue dans une fenêtre de temps spécifiée. La fonction de débouchement donne la dernière entrée vue dans une fenêtre de temps spécifiée. Les fenêtres temporelles sont également décalées en conséquence (c'est-à-dire par rapport au premier / dernier élément).
Nous voulons réaliser un comportement qui se reflète par le diagramme suivant. Par conséquent, nous allons utiliser le mécanisme de débouchement.
Nous voulons jeter tous les résultats précédents et obtenir le dernier avant la fenêtre de l'heure épuisée. En supposant que le champ de saisie a la requête ID, nous pourrions utiliser le code suivant:
<span>(function (start<span>, end</span>) { </span> <span>var n = start - 1; </span> <span>while (n++ <span>var k = Math.sqrt(n); </span> <span>var found = false; </span> <span>for (var i = 2; !found && i found <span>= n % i === 0; </span> <span>} </span> <span>if (!found) { </span> <span>postMessage(n.toString()); </span> <span>} </span> <span>} </span><span>})(2, 1e10); </span></span></span>
Dans ce code, la fenêtre est définie sur 300 ms. Nous limitons également les requêtes pour les valeurs avec au moins 3 caractères, qui sont distinctes des requêtes précédentes. Cela élimine les demandes inutiles d'entrées qui viennent d'être corrigées en tapant quelque chose et en l'effacement.
Il y a deux parties cruciales dans toute cette expression. L'un est la transformation du texte de requête en une demande utilisant la recherche, l'autre est la fonction Switch (). Ce dernier prend toute fonction qui renvoie des observables imbriqués et produit des valeurs uniquement à partir de la séquence observable la plus récente.
La fonction pour créer les demandes pourrait être définie comme suit:
<span>var worker = new Worker('prime.js'); </span>worker<span>.addEventListener('message', function (ev) { </span> <span>var primeNumber = ev.data * 1; </span> <span>console.log(primeNumber); </span><span>}, false); </span>
Notez l'observable imbriqué (qui peut entraîner des demandes non définies pour les demandes non valides), c'est pourquoi nous chouchons Switch () et où ().
Conclusions
RXJS fait de la programmation réactive en Javascript une réalité joyeuse. En tant qu'alternative, il y a aussi Bacon.js, qui fonctionne de manière similaire. Néanmoins, l'une des meilleures choses à propos de RXJS est Rx lui-même, qui est disponible sur de nombreuses plateformes. Cela rend la transition vers d'autres langues, plates-formes ou systèmes assez faciles. Il unifie également certains des concepts de programmation réactive dans un ensemble de méthodes concises et composables. En outre, plusieurs extensions très utiles existent, telles que RXJS-DOM, ce qui simplifie l'interaction avec le dom.
où voyez-vous briller Rxjs?
Des questions fréquemment posées sur la programmation réactive fonctionnelle avec RXJS
Quelle est la différence entre la programmation fonctionnelle et la programmation réactive fonctionnelle?
La programmation fonctionnelle (FP) et la programmation réactive fonctionnelle (FRP) sont toutes deux des paradigmes de programmation, mais ils ont des foyer différents. FP est un style de programmation qui traite le calcul comme l'évaluation des fonctions mathématiques et évite les données changeantes et mutables. Il met l'accent sur l'application des fonctions, contrairement au style de programmation impératif, qui met l'accent sur les changements d'état.
En revanche, le FRP est une variante de FP qui traite des flux de données asynchrones. Il combine le modèle de programmation réactive avec une programmation fonctionnelle. En FRP, vous pouvez exprimer des flux de données statiques (par exemple, tableaux) et dynamiques (par exemple, clics de souris, demandes Web) et réagir à leurs modifications.
Comment les RXJ s'intègrent-ils dans la programmation réactive fonctionnelle?
RXJS (extensions réactives pour JavaScript) est une bibliothèque de programmation réactive à l'aide d'observables, pour faciliter la composition du code asynchrone ou basé sur un rappel. Cela en fait un ajustement parfait pour la programmation réactive fonctionnelle. Avec les RXJ, vous pouvez créer des flux de données à partir de diverses sources et également transformer, combiner, manipuler ou réagir à ces flux de données à l'aide de ses opérateurs fournis.
Que sont les observables dans les RXJS?
Les observables sont des observables sont Un concept de base dans RXJS. Ce sont des flux de données, ce qui peut émettre plusieurs valeurs au fil du temps. Ils peuvent émettre trois types de valeurs: suivant, erreur et terminer. Les valeurs «suivantes» peuvent être n'importe quel objet JavaScript, «Error» est un objet d'erreur lorsque quelque chose ne va pas, et «complet» n'a pas de valeur, il signale simplement que l'observable n'émettra pas plus de valeurs.
Comment gérer les erreurs dans RXJS?
RXJS fournit plusieurs opérateurs pour gérer les erreurs, telles que Catcherror et Retry. L'opérateur Catcherror attrape l'erreur sur la source observable et continue le flux avec un nouveau observable ou une erreur. L'opérateur de réessayer remonte à la source observable lorsqu'il échoue.
Que sont les opérateurs dans RXJS?
Les opérateurs sont des fonctions pures qui permettent un puissant style de programmation fonctionnelle pour gérer les collections avec des opérations comme «MAP» «,« filtre »,« concat »,« réduction », etc. Il existe des dizaines d'opérateurs disponibles dans les RXJ qui peuvent être utilisés pour gérer des manipulations complexes de collections, qu'il s'agisse de réseaux d'articles, de flux d'événements ou même de promesses.
Comment puis-je tester mon code RXJS?
RXJS fournit des utilitaires de test, tels que TestScheduler, qui facilite le test asynchrone. Vous pouvez également utiliser des diagrammes de marbre pour visualiser les observables pendant les tests.
Puis-je utiliser des RXJ avec Angular?
Oui, RXJS est en fait un élément clé d'Angular. Il est utilisé dans le module HTTP d'Angular et également dans la classe EventEmitter qui est utilisé pour des événements personnalisés.
Quelle est la différence entre les promesses et les observables?
Les promesses et les observables traitent tous les deux des opérations asynchrones, mais elles le font de différentes manières. Une promesse est une valeur qui peut ne pas encore être disponible. Il ne peut être résolu (rempli ou rejeté) qu'une seule fois. D'un autre côté, un observable est un flux de valeurs qui peut émettre zéro ou plus de valeurs, et il peut être abonné ou non publié.
Comment puis-je me désinscrire d'un?
Lorsque vous vous abonnez à un observable, vous obtenez un objet d'abonnement. Vous pouvez appeler la méthode de désabonnement sur cet objet pour annuler l'abonnement et arrêter de recevoir des données.
Quels sont les sujets dans RXJS?
Les sujets en RXJ sont un type spécial d'observable qui permet multidiffusion à de nombreux observateurs. Contrairement aux observables simples, les sujets maintiennent un registre de nombreux auditeurs.Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Le choix de Python ou JavaScript doit être basé sur le développement de carrière, la courbe d'apprentissage et l'écosystème: 1) le développement de carrière: Python convient à la science des données et au développement de back-end, tandis que JavaScript convient au développement frontal et complet. 2) Courbe d'apprentissage: la syntaxe Python est concise et adaptée aux débutants; La syntaxe JavaScript est flexible. 3) Ecosystème: Python possède de riches bibliothèques informatiques scientifiques, et JavaScript a un puissant cadre frontal.

La puissance du cadre JavaScript réside dans la simplification du développement, l'amélioration de l'expérience utilisateur et les performances des applications. Lorsque vous choisissez un cadre, considérez: 1. Taille et complexité du projet, 2. Expérience d'équipe, 3. Écosystème et soutien communautaire.

INTRODUCTION Je sais que vous pouvez le trouver étrange, que doit faire exactement JavaScript, C et Browser? Ils semblent sans rapport, mais en fait, ils jouent un rôle très important dans le développement Web moderne. Aujourd'hui, nous discuterons du lien étroit entre ces trois. Grâce à cet article, vous apprendrez comment JavaScript fonctionne dans le navigateur, le rôle de C dans le moteur du navigateur et comment ils fonctionnent ensemble pour stimuler le rendu et l'interaction des pages Web. Nous connaissons tous la relation entre JavaScript et Browser. JavaScript est la langue principale du développement frontal. Il fonctionne directement dans le navigateur, rendant les pages Web vives et intéressantes. Vous êtes-vous déjà demandé pourquoi javascr

Node.js excelle dans des E / S efficaces, en grande partie grâce aux flux. Streams traite les données progressivement, en évitant la surcharge de mémoire - idéal pour les fichiers volumineux, les tâches réseau et les applications en temps réel. Combiner les flux avec la sécurité de type dactylographié crée un powe

Les différences de performance et d'efficacité entre Python et JavaScript se reflètent principalement dans: 1) comme un langage interprété, Python fonctionne lentement mais a une efficacité de développement élevée et convient au développement rapide des prototypes; 2) JavaScript est limité au thread unique dans le navigateur, mais les E / S multi-threading et asynchrones peuvent être utilisées pour améliorer les performances dans Node.js, et les deux ont des avantages dans les projets réels.

JavaScript est originaire de 1995 et a été créé par Brandon Ike, et a réalisé que la langue en langue C. 1.C offre des capacités de programmation élevées et au niveau du système pour JavaScript. 2. La gestion de la mémoire de JavaScript et l'optimisation des performances reposent sur le langage C. 3. La fonctionnalité multiplateforme du langage C aide JavaScript à s'exécuter efficacement sur différents systèmes d'exploitation.

JavaScript s'exécute dans les navigateurs et les environnements Node.js et s'appuie sur le moteur JavaScript pour analyser et exécuter du code. 1) Générer une arborescence de syntaxe abstraite (AST) au stade d'analyse; 2) Convertir AST en bytecode ou code machine à l'étape de compilation; 3) Exécutez le code compilé à l'étape d'exécution.

Les tendances futures de Python et JavaScript incluent: 1. Python consolidera sa position dans les domaines de l'informatique scientifique et de l'IA, 2. JavaScript favorisera le développement de la technologie Web, 3. Le développement de plate-forme multiplié deviendra un sujet brûlant, et 4. L'optimisation des performances sera le focus. Les deux continueront d'étendre les scénarios d'application dans leurs champs respectifs et de faire plus de percées dans les performances.


Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

MantisBT
Mantis est un outil Web de suivi des défauts facile à déployer, conçu pour faciliter le suivi des défauts des produits. Cela nécessite PHP, MySQL et un serveur Web. Découvrez nos services de démonstration et d'hébergement.

MinGW - GNU minimaliste pour Windows
Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.

mPDF
mPDF est une bibliothèque PHP qui peut générer des fichiers PDF à partir de HTML encodé en UTF-8. L'auteur original, Ian Back, a écrit mPDF pour générer des fichiers PDF « à la volée » depuis son site Web et gérer différentes langues. Il est plus lent et produit des fichiers plus volumineux lors de l'utilisation de polices Unicode que les scripts originaux comme HTML2FPDF, mais prend en charge les styles CSS, etc. et présente de nombreuses améliorations. Prend en charge presque toutes les langues, y compris RTL (arabe et hébreu) et CJK (chinois, japonais et coréen). Prend en charge les éléments imbriqués au niveau du bloc (tels que P, DIV),

Télécharger la version Mac de l'éditeur Atom
L'éditeur open source le plus populaire
