Cet article présente principalement l'histoire de l'évolution asynchrone d'Express. L'éditeur le trouve plutôt bien. Maintenant, je le partage avec vous et le donne comme référence. Venez jeter un œil avec l'éditeur
1 Introduction
Dans le monde du Javascript, asynchrone (en raison du fonctionnement monothread. de JavaScript, donc async en JavaScript peut bloquer) est partout.
Express est un framework de serveur Web très populaire dans l'environnement de nœud. Une grande partie des applications Web Node utilisent Express.
Lorsque nous utilisons JavaScript pour écrire du code côté serveur, nous utiliserons inévitablement beaucoup l'asynchronie. À mesure que JavaScript et Node évoluent, nos méthodes de traitement asynchrone évolueront également.
Ensuite, jetons un coup d'œil à l'évolution du traitement asynchrone dans Express.
2. Traitement asynchrone de JavaScript
Dans le monde asynchrone, nous devons trouver un moyen d'obtenir la notification de l'achèvement du méthode asynchrone, alors Quelles sont les méthodes en JavaScript ?
2.1. Rappel
Le rappel est le mécanisme de notification asynchrone le plus original et le plus ancien de JS.
function asyncFn(callback) { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); callback(); // 发通知 }, 2000); } asyncFn(function () { console.log('我会在2s后输出'); });
2.2. Surveillance des événements
Fonction pour obtenir le résultat, écouter pendant un certain temps. Une fois la méthode asynchrone terminée, l'événement est déclenché pour obtenir l'effet de notification.
2.3. Publier/Abonnez-vous
Utilisez le mode observateur pour modifier l'éditeur une fois terminé de manière asynchrone. A ce moment, l'éditeur informera les abonnés des modifications.
2.4, Promise
Promise est une amélioration de la fonction de rappel. En utilisant cela, nous pouvons paralléliser l’asynchronie et éviter l’enfer des rappels.
function asyncFn() { return new Promise((resolve, reject) => { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); resolve(); // 发通知(是否有感觉到回调的影子?) }, 2000); }); } asyncFn() .then(function () { console.log('我会在2s后输出'); });
2.5. Générateur
La fonction Générateur est une solution de programmation asynchrone fournie par ES6.
Le code suivant n'est qu'une simple démonstration. En fait, le processus d'utilisation de Generator est relativement compliqué. C'est un autre sujet et ne sera pas abordé dans cet article.
function asyncFn() { return new Promise((resolve, reject) => { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); resolve(); // 发通知(是否有感觉到回调的影子?) }, 2000); }); } function* generatorSync() { var result = yield asyncFn(); } var g = generatorSync(); g.next().value.then(()=>{ console.log('我会在2s后输出'); });
2.6, async...await
peut être considéré comme la meilleure solution pour gérer l'asynchrone dans le courant Javascript.
function asyncFn() { return new Promise((resolve, reject) => { // 利用setTimeout模拟异步 setTimeout(function () { console.log('执行完毕'); resolve(); // 发通知(是否有感觉到回调的影子?) }, 2000); }); } async function run(){ await asyncFn(); console.log('我会在2s后输出'); } run();
3. Traitement asynchrone dans Express
Dans Express, nous utilisons généralement The best les solutions sont : la fonction de rappel, la Promesse et l'asynchrone... attendez.
Afin de créer un environnement de démonstration, initialisez un projet express via express-generator. Généralement, les projets côté serveur utilisent des routes pour appeler la logique métier. Par conséquent, nous suivons également ce principe :
Ouvrez routs/index.js, et nous verrons le contenu suivant. La démo suivante utilisera ce fichier pour la démonstration.
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); module.exports = router;
3.1. La fonction de rappel gère la logique asynchrone Express
Dans Express, le routage peut charger plusieurs middlewares afin que nous puissions. écrire la logique métier selon la méthode d'écriture du middleware. De cette manière, la logique asynchrone peut être divisée de manière très pratique en plusieurs couches.
var express = require('express'); var router = express.Router(); function asyncFn(req, res, next) { setTimeout(() => { req.user = {}; // 设置当前请求的用户 next(); }, 2000); } function asyncFn2(req, res, next) { setTimeout(() => { req.auth = {}; // 设置用户权限 next(); }, 2000); } function asyncFn3(req, res, next) { setTimeout(() => { res.locals = { title: 'Express Async Test' }; // 设置数据 res.render('index'); // 响应 }, 2000); } /* GET home page. */ router.get('/', asyncFn, asyncFn2, asyncFn3); // 一步步执行中间件 module.exports = router;
3.2. Traitement des promesses Logique asynchrone express
Dans cette solution, plusieurs logiques métier sont regroupées en tant que fonctions de promesse de retour. . Passez des appels combinés via des méthodes commerciales pour obtenir l'effet d'un entrant et d'un sortant.
var express = require('express'); var router = express.Router(); function asyncFn(req, res) { return new Promise((resolve, reject) => { setTimeout(() => { req.user = {}; // 设置当前请求的用户 resolve(req); }, 2000); }); } function asyncFn2(req) { return new Promise((resolve, reject) => { setTimeout(() => { req.auth = {}; // 设置用户权限 resolve(); }, 2000); }); } function asyncFn3(res) { return new Promise((resolve, reject) => { setTimeout(() => { res.locals = { title: 'Express Async Test' }; // 设置数据 res.render('index'); // 响应 }, 2000); }); } function doBizAsync(req, res, next) { asyncFn(req) .then(() => asyncFn2(req)) .then(() => asyncFn3(res)) .catch(next); // 统一异常处理 }; /* GET home page. */ router.get('/', doBizAsync); module.exports = router;
3.3. async...wait gère la logique asynchrone express
En fait, cette solution nécessite également Promise It est pris en charge, mais la méthode d'écriture est plus intuitive et la gestion des erreurs est plus directe.
Il convient de noter qu'Express est une première solution et n'a pas de gestion globale des erreurs pour async... wait, elle peut donc être gérée par packaging.
var express = require('express'); var router = express.Router(); function asyncFn(req) { return new Promise((resolve, reject) => { setTimeout(() => { req.user = {}; // 设置当前请求的用户 resolve(req); }, 2000); }); } function asyncFn2(req) { return new Promise((resolve, reject) => { setTimeout(() => { req.auth = {}; // 设置用户权限 resolve(); }, 2000); }); } function asyncFn3(res) { return new Promise((resolve, reject) => { setTimeout(() => { }, 2000); }); } async function doBizAsync(req, res, next) { var result = await asyncFn(req); var result2 = await asyncFn2(req); res.locals = { title: 'Express Async Test' }; // 设置数据 res.render('index'); // 响应 }; const tools = { asyncWrap(fn) { return (req, res, next) => { fn(req, res, next).catch(next); // async...await在Express中的错误处理 } } }; /* GET home page. */ router.get('/', tools.asyncWrap(doBizAsync)); // 需要用工具方法包裹一下 module.exports = router;
4. Résumé
Bien que le koa soit utile pour une utilisation plus récente et meilleure (koa C'est un générateur, koa2 natif async) supporte mieux. Mais en tant que personne ayant commencé à travailler avec le nœud 0.x, j'ai toujours un penchant particulier pour Express.
Certaines des solutions ci-dessus sont déjà utilisées dans le koa et, combinées à l’immense écosystème d’Express, elles sont encore plus puissantes.
Adresse Github de cet article
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!