Lorsque nous écrivons le backend express, nous devons souvent gérer de nombreuses E/S asynchrones. Dans les temps anciens, nous utilisions tous la fonction chunk, qui est la fonction que nous connaissons le mieux et dont le premier paramètre par défaut est error
. Simulons le fonctionnement d'une base de données Mongo et prenons-en une idée.
Cet article présente principalement comment NodeJs gère le traitement asynchrone via async/await. Le contenu est assez bon. Maintenant, je le partage avec vous et vous donne une référence, j'espère qu'il pourra vous aider.
mongoDb.open(function(err, db){ if(!err){ db.collection("users", function(err, collection){ if(!err){ let person = {name: "yika", age: 20}; collection.insert(person, function(err, result){ if(!err){ console.log(result); } }); } }) } });
C'est ce que nous avons critiqué callback hell
, un tas de pyramides horizontales si les rappels sont divisés en fonctions, ils deviendront très fragmentés. Afin d'éviter que tout le monde ne soit dégoûté, je n'ai même pas écrit sur la gestion des erreurs. Normalement, chaque opération asynchrone doit être affichée ou traitée en conséquence avec son error
.
L'ère de la promesse
Plus tard, nous sommes entrés dans une meilleure ère de la promesse, que nous pouvons également appeler les opérations en chaîne. Concernant Promise, j'ai déjà écrit une série d'articles de blog. Si vous êtes intéressé, vous pouvez le relire. Jetons un coup d'œil à la situation après avoir réécrit ce qui précède.
let person = {name: "yika"}; mongoDb .open() .then(function(database){ return database.collection("users"); }) .then(function(collection){ return collection.insert(person); }) .then(function(result){ console.log(result); }) .catch(function(e){ throw new Error(e); })
Nous pouvons voir que nous avons aplati la pyramide en une structure linéaire. Par rapport à la fonction chunk précédente, qui était dégoûtante et difficile à maintenir, elle est devenue une fonction promise et la gestion des erreurs est devenue très élégante. Mais nous ne pouvons toujours pas ignorer certains problèmes.Par exemple, nous devons supporter que chaque logique soit enveloppée l'une après l'autre.Si vous souhaitez partager certaines données, elles doivent être suspendues dans la couche la plus externe. le plus important c'est qu'elle reste quand même différente de la programmation synchrone que l'on connaît. then()
Generator Era
Master TJ, à travers l'itérateur Generator d'ES6, a été le premier à réaliser la fonction de synchronisation de la programmation asynchrone, qui est la plus connue de nousBibliothèque. Nous utilisons co
pour contrôler la fonction en interne via des itérateurs. Et co(function *(){})
fait ici office de lanceur. J'ai dit la même chose à propos de Generator and co dans mon précédent article de blog. co
let co = require("co"); co(function *(){ let db, collection, result; let person = {name: "yika"}; try{ db = yield mongoDb.open(); collection = yield db.collection("users"); result = yield collection.insert(person); }catch(e){ console.error(e.message); } console.log(result); });
. Mais ce que nous devons admettre, c’est que les itérateurs n’existent pas pour l’asynchronisme après tout. La sémantique de try and catch
et yield
à l'intérieur ne représente pas les indicateurs de fonction asynchrone. Et l'itérateur doit être piloté par co, ce qui est un peu différent de la fonction que nous imaginions. *
ère asynchrone/attente
Nous avons prêté attention à l'ère asynchrone/attente d'ES7, pour découvrir que c'est ce que nous voulons ! Réécrivons légèrement le code ci-dessus.async function insertData(person){ let db, collection, result; try{ db = await mongoDb.open(); collection = await db.collection("users"); result = await collection.insert(person); }catch(e){ console.error(e.message); } console.log(result); } insertData({name: "yika"});
est une vraie fonction que l'on peut appeler directement sans avoir besoin d'un pilote de lanceur. Bien sûr, en interne on sent aussi qu'il n'y a pas de grande différence sauf que inserData
a été changé en yield
. async/await est plus conforme à la sémantique de notre programmation asynchrone. await
Utiliser
Comme nous l'avons dit au début, babel prend déjà en charge la transformation asynchrone. introduisons Babel lorsque nous l'utilisons. Bien entendu, le côté serveur et le côté navigateur peuvent avoir des méthodes de traitement différentes. Avant de commencer, nous devons introduire le package suivant Preset-stage-3 contenant les fichiers compilés async/await dont nous avons besoin.$ npm install babel-core --save $ npm install babel-preset-es2015 --save $ npm install babel-preset-stage-3 --save
Côté navigateur
Babel est apparu à l'origine pour permettre aux anciens navigateurs de prendre en charge les nouveaux. Fonctionnalités ES6 à améliorer notre expérience de développement. Babel peut donc être compilé via le terminal babel-cli depuis le début. Ou introduisez des fichiers babel à compiler côté navigateur. Bien sûr, ce ne sont pas ceux que je recommande le plus, je vais donc les laisser de côté. Dans la configuration des ressources statiques frontales, webpack est désormais une meilleure solution. Il prend en charge les dépendances de module des ressources statiques, l'empaquetage et la fusion, ainsi que le prétraitement du langage. Bien sûr, nous faisons ici référence au traitement Babel.// webpack.config.js // 省略上面的文件输入输出的配置,直接看模块加载器的配置 module: { loaders: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, loader: "babel", query: { presets: ['es2015', 'stage-3'] } }, ] }
Côté serveur
Relativement parlant, le back-end doit gérer beaucoup plus d'emplacements d'E/S asynchrones que le front-end, et il en a également davantage besoin. Alors, comment introduire Babel côté serveur ? En fait, la méthode la plus simple et la plus gênante consiste à compiler directement le fichier js via babel pour créer un nouveau fichier puis à l'utiliser. Bien entendu, les fichiers redondants sont inévitables. Loin des yeux, loin du cœur, essayons une autre méthode. Nous utilisons la méthode de hook require officiellement fournie. Comme son nom l'indique, après avoir passé par require, les prochains fichiers seront traités par Babel lorsqu'ils seront requis. Parce que nous savons que CommonJs est une dépendance de module synchrone, c'est également une méthode réalisable. Nous avons besoin d'un fichier js supplémentaire pour le démarrage, un fichier js qui exécute réellement le programme.// index.js // 用于引入babel,并且启动app.js require("babel-core/register"); require("./app.js");
配置完hook之后,我们就配置babel的.babelrc文件,它是一个json格式的文件。es2015看情况配置,如果是已经是Node5.0版本,就无需再进行编译。
{ "presets": ["stage-3", "es2015"] }
最后我们的异步函数代码,写在app.js里即可。
相关推荐:
以jQuery中$.Deferred对象为例讲解promise对象是如何处理异步问题_jquery
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!