Les générateurs sont un style Coroutine (Coroutine) de JavaScript. Il fait référence aux fonctions qui peuvent être interrompues puis reprise lors de l'exécution. La fonction est accompagnée de symboles d'astérisque dans la fonction, tels que la fonction *, et certains mots clés caractéristiques de la fonction, tels que le rendement et le rendement *.
Fonction * GeneratorFn () {console.log ('look ma i a été suspendu')} var générateur = générateurfn () // [1] setTimeout (function () {generator.next () // [2]}, 2000)Les [1] et [2] marqués dans le code sont expliqués comme suit:
1. Il s'agit d'un générateur qui commence par une pause. Il n'y a pas de sortie de console pour le moment.
2. Ce n'est qu'en appelant sa méthode suivante () que le générateur peut être exécuté et exécuter jusqu'à ce qu'il rencontre le mot clé ou retour à rendement suivant. Nous avons maintenant la sortie de la console.
Regardons un autre cas:
fonction * générateur () {console.log ('start!'); var i = 0; while (true) {if (i <3) rende i ++; }} var gen = générateur ();Le code ci-dessus est similaire au premier, mais il y a un mot clé de rendement supplémentaire dans la fonction du générateur. Lorsque le code ci-dessus est appelé, il ne sera pas exécuté immédiatement, mais en suspendra l'état de veille, il n'y aura donc pas de sortie de démarrage. Il n'est pas exécuté avant son prochain appel ().
var ret = gen.next (); // start! console.log (ret); // {valeur: 0, fait: false}Le RET ci-dessus est le résultat du générateur. Il a deux propriétés:
■ valeur, valeur de rendement dans la fonction du générateur,
■ Terminé, il s'agit d'un indicateur indiquant si la fonction du générateur retourne.
Continuez le code comme suit:
console.log (gen.next ()); // {valeur: 1, fait: false} console.log (gen.next ()); // {valeur: 2, fait: false} console.log (gen.next ()); // {valeur: Undefined, Done: true}Le générateur n'a pas de mystère dans la programmation synchrone et convient particulièrement à la programmation asynchrone.
Le générateur a deux caractéristiques:
1. Vous pouvez choisir de sauter d'une fonction, laissez le code externe décider quand revenir à cette fonction et continuer à exécuter.
2. Capable d'effectuer un contrôle asynchrone.
Regardez le code d'exécution asynchrone suivant:
var gen = générateur (); console.log (gen.next (). Valeur); setTimeout (function () {console.log (gen.next (). valeur); console.log ('première étape');}, 1000); console.log ('deuxième étape');La sortie est:
0
Étape 2
1
premier pas
En d'autres termes, vous n'attendez pas que le délai d'attente se termine à Settimeout, mais vous continuera directement avec la "deuxième étape" et ne sera pas bloqué sur Settimeout.
Regardons un autre morceau de code:
fonction * canal () {var name = rendement 'Bonjour, quel est votre nom?' // [1] return 'bien salut' + name} var gen = channel () console.log (gen.next (). Valeur) // Bonjour, quel est votre nom? [2] console.log (gen.next ('billy')) // bien salut billy [3]Vous pouvez également utiliser * pendant la traversée:
fonction * iter () {for (var i = 0; i <10; i ++) rendement i} pour (var val of iter ()) {console.log (val) // sort 1? -? 9}Malentendus communs
Puisque je peux suspendre une exécution de fonction, dois-je les laisser exécuter en parallèle? Non, parce que JavaScript est un seul fil, et si vous voulez demander des améliorations de performances, le générateur n'est pas votre plat.
Par exemple, le code suivant exécute séparément les numéros Fibonacci:
fonction fib (n) {var current = 0, next = 1, swap for (var i = 0; i <n; i ++) {swap = current, current = next = swap + next} return current} function * fibgen (n) {var current = 0, next = 1, swap pour (var i = 0; i <n; i ++) {swap = actuel, actuel = nez suivante = Swap +Les résultats des performances sont les suivants: (Plus il y a, mieux c'est)
Résultats:
Régulier 1263899
générateur 37541
Les générateurs brillent
Les générateurs peuvent simplifier la complexité des fonctions dans JavaScript.
Affectation paresseuse
Bien que l'affectation paresseuse puisse être mise en œuvre à l'aide de fermetures JS, l'utilisation du rendement sera considérablement simplifié. Grâce à la pause et à la récupération, nous pouvons obtenir des valeurs numériques lorsque nous en avons besoin. Par exemple, la fonction fibgen ci-dessus peut extraire de nouvelles valeurs lorsque nous en avons besoin:
var fibiter = fibgen (20) var next = fibiter.next () console.log (next.value) setTimeout (function () {var next = fibiter.next () console.log (next.value)}, 2000) bien sûr, il utilise également un pour la boucle: il est toujours Lazy pour affecter (var n de fibgen (20) {console.log (n)}Séquence infinie
Parce que vous pouvez être paresseux pour attribuer des valeurs, vous pouvez effectuer des astuces Haskell, similaires aux séquences infinies. Ici, vous pouvez produire le nombre d'une séquence infinie.
Fonction * fibgen () {var current = 0, next = 1, swap while (true) {swap = current, current = next Suivant = swap + nex rendement net}}Examinons l'affectation paresseuse d'un fluxacci et demandez-lui de retourner le premier numéro Fibonacci après 5000:
pour (var num de fibgen ()) {if (num> 5000) Break} console.log (num) // 6765Contrôle de processus asynchrone
Utilisation de générateurs pour implémenter le contrôle des processus asynchrones, le plus souvent divers packages de bibliothèque de promesses, alors comment cela fonctionne-t-il?
Dans le monde des nœuds, tout est lié aux rappels, qui est notre fonction asynchrone de bas niveau. Nous pouvons utiliser des générateurs pour créer un canal de communication, afin d'écrire du code asynchrone dans le style de la programmation synchrone.
run (function * () {console.log ("démarrage") var file = rendement readFile ("./ async.js") // [1] console.log (file.tostring ())})La note 1 signifie que le programme se poursuivra avant d'attendre que Async.JS renvoie le résultat.
Genify est un cadre qui amène les générateurs dans un environnement de programmation normal, en utilisant les éléments suivants:
NPM Install Genify for Installation, le code est le suivant:
var q = require ('q'); var fs = require ('fs'); var genify = requif ('génie'); // Enveloppez votre objet dans Genify functionVar Object = Genify ({ConcatFiles: fonction * (file1, file2, outfile) {file1 = rendement q.nfcall (fs.readfile, file1); file2 = rendement q.nfcall (fs.readfile, file2); var Concated = file1 + file2; reverse; conçu;}}); // ConcatFiles est une fonction de générateur qui utilise les capacités puissantes des générateurs. object.concatfiles ('./ somefile1.txt', './somefile2.txt', './conquet.txt' ).then(Function (res) {// faire quelque chose avec le résultat}, fonction (err) {// faire quelque chose avec l'erreur});L'explication détaillée ci-dessus de l'utilisation de générateurs JavaScript dans Node.js est tout le contenu que je partage avec vous. J'espère que vous pourrez vous faire référence et j'espère que vous pourrez soutenir Wulin.com plus.