Synchrone et asynchrone
introduction
À mesure que les applications Web continuent de se développer, JavaScript, en tant que langage de programmation largement utilisé, se développe et évolue également constamment. Dans le développement frontal Web, JavaScript est principalement utilisé pour le traitement de l'interface utilisateur du navigateur. Le développement de l'interface utilisateur est un modèle typique piloté par des événements à thread unique, de sorte que JavaScript a également formé un paradigme de programmation avec le traitement asynchrone comme paradigme de programmation principal. Cependant, dans les applications complexes et à grande échelle, les problèmes et la complexité causés par la programmation asynchrone deviennent de plus en plus évidents.
L'émergence de Node.js apporte un nouveau paradigme de programmation asynchrone à JavaScript : les boucles d'événements et les fonctions de rappel. Ce paradigme de programmation est efficace et concis, et convient aux scénarios à forte concurrence et à forte intensité d'E/S. Cependant, ce paradigme de programmation apporte également ses propres problèmes et complexités.En particulier dans les applications complexes et à grande échelle, les programmeurs doivent faire face au problème de l'imbrication de nombreuses fonctions de rappel et doivent faire face au problème de l'ordre des appels asynchrones, ce qui augmente la complexité. et la difficulté du programme.
Afin de résoudre ces problèmes et difficultés, les fibjs ont vu le jour. fibjs est un framework de développement de serveur d'applications principalement conçu pour le développement web back-end. Il est basé sur le moteur JavaScript Google v8 et choisit une solution de concurrence différente du rappel traditionnel. fibjs utilise la fibre pour isoler la complexité métier causée par les appels asynchrones au niveau de la couche framework, réduisant ainsi considérablement la difficulté de développement et réduisant les problèmes de performances causés par un traitement asynchrone fréquent dans l'espace utilisateur. Dans le même temps, par rapport au paradigme de programmation asynchrone traditionnel, son paradigme de programmation synchrone présente les avantages d'une plus grande lisibilité, d'une logique simple et d'une maintenance facile.
Dans le contenu suivant, nous présenterons les avantages et les fonctionnalités de fibjs, et expliquerons comment utiliser ses solutions de programmation synchrone et asynchrone à travers des exemples.
introduction aux fibres
fibjs est un framework de serveur JavaScript hautes performances basé sur le moteur v8, principalement destiné au développement back-end Web. Lancé en 2009, il présente déjà une stabilité et une productivité élevées et dispose d'un large éventail de cas d'application dans le pays et à l'étranger.
Dans fibjs, la fibre est utilisée pour résoudre le problème entre la logique métier et le traitement des E/S. La fibre est différente des concepts traditionnels tels que les threads, les coroutines et les processus. Il s'agit d'un thread léger au niveau de l'utilisateur qui peut être considéré comme un mécanisme multitâche coopératif. La fibre peut exécuter une logique métier et des opérations d'E/S dans différents contextes et gère les ressources en interne via la pré-allocation et le recyclage. Par rapport aux threads et processus traditionnels, elle est plus légère, plus flexible et plus efficace.
Par rapport à d'autres bibliothèques de threads (telles que pthread, WinThread, Boost.Thread, etc.), la fibre présente les avantages suivants :
Planification collaborative : Fiber est une planification collaborative qui ne nécessite pas de planification préemptive de la part du noyau ou du système d'exploitation. Elle réduit les changements de contexte fréquents, accélère la vitesse d'exécution du programme et évite les conditions de concurrence et les problèmes de blocage entre les threads.
Léger : chaque fibre ne consomme qu'un petit espace de pile, et un grand nombre de fibres peuvent être créées dans des applications multi-simultanées sans poser le problème d'occuper trop de mémoire.
Efficacité : la fibre est implémentée sur la base des caractéristiques du langage JavaScript lui-même et exploite pleinement les performances supérieures du moteur v8, qui est plus rapide que les bibliothèques de threads traditionnelles.
En utilisant la fibre, les fibjs peuvent séparer la logique métier et le traitement des E/S, encapsulant ainsi les appels asynchrones sous la forme d'appels synchrones, rendant l'écriture et la maintenance du code plus simples et plus faciles à lire, et en même temps faisant pleinement valoir les avantages du Langage JavaScript.
Programmation synchrone en fibjs
En programmation asynchrone, l'imbrication des fonctions de rappel peut conduire à une mauvaise lisibilité du code, provoquer facilement le problème de l'enfer des rappels et augmenter la difficulté du code et le coût du débogage. Le paradigme de programmation synchrone est plus conforme aux modèles de pensée humaine, rendant la structure du code plus claire, plus facile à lire et à maintenir, ce qui peut grandement améliorer l'efficacité du développement et la qualité du code.
Dans fibjs, la programmation synchrone est un paradigme de programmation très populaire et couramment utilisé, qui rend la structure et la logique du code plus intuitives, faciles à comprendre et à maintenir. Certaines fonctions et modules de programmation synchrone sont hautement pris en charge dans fibjs, tels que util.sync, fs.readSync, etc.
Dans fibjs, vous pouvez appeler directement les fonctions asynchrones des objets intégrés de manière synchrone :
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
Vous pouvez également envelopper la fonction asynchrone via util.sync et try...catch, afin que la fibre puisse obtenir la valeur de retour de l'appel asynchrone, obtenant ainsi l'effet de synchronisation, par exemple :
1
2
3
4
5
6
7
8
9
10
11
12
13// load module
const coroutine = require("coroutine");
const util = require("util");
const fs = require("fs");
// use util.sync to wrap fs.readFile
function readFile(path) {
return util.sync(fs.readFile)(path);
}
// call the sync function
const data = readFile("myfile.txt");
console.log(data);
Dans l'exemple ci-dessus, nous avons défini une fonction nommée readFile et utilisé util.sync pour encapsuler la fonction asynchrone fs.readFile dans une fonction synchrone. Cette fonction peut renvoyer directement des données via des appels synchrones. Cette méthode d'appel synchrone est similaire au paradigme de programmation JavaScript traditionnel. La différence est que dans fibjs, le thread n'est pas bloqué, mais l'effet asynchrone est obtenu via la fibre.
Comment fonctionne util.sync
util.sync est une fonction wrapper efficace du noyau. Le code JavaScript suivant peut réaliser des fonctions similaires :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const coroutine = require("coroutine");
function sync(func) {
return function _warp() {
var ev = new coroutine.Event();
var e, r;
func.apply(this, [
...arguments,
function (err, result) {
e = err;
r = result;
ev.set();
}
]);
ev.wait();
if (e)
throw e;
return r;
}
}
Ce code définit une fonction d'outil de synchronisation pour convertir une fonction de rappel asynchrone en une fonction d'appel synchrone. Il reçoit une fonction func et renvoie une nouvelle fonction _wrap. Cette nouvelle fonction implémente la fonction de conversion de la fonction d'origine en un appel synchrone. Dans la fonction _wrap, un nouvel objet Event ev est d'abord créé pour la planification des threads et en attente des résultats de rappel asynchrone. Utilisez ensuite la méthode apply pour appeler la fonction d'origine func avec les paramètres spécifiés et une nouvelle fonction de rappel comme paramètres. Pendant le processus d'appel, un rappel asynchrone se produit et la nouvelle fonction de rappel stocke les résultats renvoyés dans les variables e et r et réveille l'objet Event. Enfin, il est décidé en fonction de la variable e de lever une exception ou de renvoyer la variable r. Cette fonction implémente une solution pour convertir les fonctions de rappel asynchrones en appels synchrones, ce qui peut améliorer la lisibilité et la maintenabilité de la fonction.
Programmation asynchrone en fibjs
Dans fibjs, la plupart des méthodes asynchrones (y compris les méthodes d'E/S et de requête réseau, etc.) peuvent prendre en charge les appels synchrones et asynchrones, ce qui permet aux développeurs de choisir à tout moment la méthode à utiliser en fonction de leurs besoins de programmation.
En prenant fs.readFile() comme exemple, nous pouvons utiliser cette méthode de deux manières :
Méthode asynchrone : Traitez le résultat de la lecture du fichier en passant une fonction de rappel, par exemple :
1
2
3
4
5
6const fs = require("fs");
fs.readFile("/path/to/file", (err, data) => {
if (err) throw err;
console.log(data);
});
Cette méthode convient aux situations où vous devez effectuer certaines opérations après avoir lu le fichier.
Méthode synchrone : obtenez le contenu du fichier en ne passant pas de fonction de rappel, par exemple :
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
Dans cet exemple, nous obtenons le contenu du fichier en lisant les données de valeur de retour du fichier. Il n'est pas nécessaire d'attendre que la fonction de rappel termine la lecture du fichier avant de poursuivre l'opération. Cette méthode convient aux situations dans lesquelles vous devez effectuer certaines opérations avant la fin de la lecture du fichier.
On peut voir que cette fonctionnalité de prise en charge des appels synchrones et asynchrones permet aux développeurs de choisir d'utiliser différentes méthodes en fonction de leurs propres besoins et scénarios de développement. Dans certains cas, le code synchrone est plus lisible et plus facile à maintenir et à déboguer ; tandis que dans certains cas, le code asynchrone peut mieux améliorer la vitesse de réponse et les performances du code.
Cependant, vous devez être prudent lorsque vous utilisez la méthode de synchronisation, car dans certains scénarios, cette méthode peut bloquer la fibre actuelle. Nous devons donc choisir la méthode de programmation appropriée en fonction des besoins réels.
en conclusion
Dans cet article, nous présentons le style de programmation synchrone et les solutions de programmation asynchrone des fibjs ainsi que leurs avantages et scénarios d'application. Nous avons mentionné que les fibjs peuvent réduire la complexité opérationnelle et améliorer l'efficacité du développement de code en utilisant la fibre pour isoler les problèmes de logique métier et de performances causés par le traitement asynchrone. Dans le même temps, nous avons également souligné les avantages des fibjs dans le traitement des E/S et la gestion de la mémoire, ce qui apporte une grande commodité au développement, aux tests et à la maintenance.
Enfin, nous encourageons les lecteurs à explorer le fibjs en profondeur et à participer aux contributions et aux activités communautaires du fibjs. Nous pensons que fibjs continuera d'attirer l'attention et le soutien de la communauté open source grâce à ses performances puissantes et sa facilité d'utilisation.