J'ai essayé de trouver une bonne description de ce que fait la méthode next()
. Dans la documentation Express, il est indiqué que next('route')
peut être utilisé pour accéder à cette route et ignorer toutes les routes entre les deux, mais parfois next
est appelé sans arguments. Quelqu'un connaît-il un bon tutoriel, etc., qui décrit la fonction next
?
next()
sans argument dit "je plaisante, je ne veux pas vraiment gérer ça". Il retourne et tente de trouver le prochain itinéraire qui correspondrait.
Ceci est utile, par exemple, si vous voulez avoir un gestionnaire de pages avec des slugs d’URL, ainsi que beaucoup d’autres choses, mais voici un exemple.
app.get('/:pageslug', function(req, res, next){
var page = db.findPage(req.params.pageslug);
if (page) {
res.send(page.body);
} else {
next();
}
});
app.get('/other_routes', function() {
//...
});
Ce code composé devrait vérifier une base de données pour une page avec un certain slug id. S'il en trouve un, rendez-le! s'il n'en trouve pas, ignorez ce gestionnaire d'itinéraires et recherchez-en d'autres.
Donc, next()
sans argument permet de prétendre que vous n’avez pas géré la route de sorte que quelque chose d’autre puisse la récupérer.
Ou un compteur de coups avec app.all('*')
. Ce qui vous permet d'exécuter du code d'installation partagé, puis de passer à d'autres itinéraires pour effectuer quelque chose de plus spécifique.
app.all('*', function(req, res, next){
myHitCounter.count += 1;
next();
});
app.get('/other_routes', function() {
//...
});
Dans la plupart des frameworks, vous recevez une demande et vous souhaitez renvoyer une réponse. En raison de la nature asynchrone de Node.js, vous rencontrez des problèmes de rappel imbriqué si vous effectuez des tâches non triviales. Pour que cela ne se produise pas, Connect.js (avant la v4.0, Express.js était une couche au-dessus de connect.js) comportait un middleware, qui est une fonction avec 2, 3 ou 4 paramètres.
function (<err>, req, res, next) {}
Votre application Express.js est une pile de ces fonctions.
Le routeur est spécial, c'est un middleware qui vous permet d'exécuter un ou plusieurs middleware pour une certaine URL. Donc, c'est une pile à l'intérieur d'une pile.
Alors, que fait-on ensuite? Simple, il indique à votre application d'exécuter le prochain middleware. Mais qu'advient-il lorsque vous passez quelque chose à la prochaine? Express abandonne la pile actuelle et exécute tous les middlewares comportant 4 paramètres.
function (err, req, res, next) {}
Ce middleware est utilisé pour traiter les erreurs éventuelles. J'aime faire les choses suivantes:
next({ type: 'database', error: 'datacenter blew up' });
Avec cette erreur, je dirais probablement à l'utilisateur que quelque chose s'est mal passé et consignera la véritable erreur.
function (err, req, res, next) {
if (err.type === 'database') {
res.send('Something went wrong user');
console.log(err.error);
}
};
Si vous décrivez votre application Express.js comme une pile, vous pourrez probablement résoudre vous-même beaucoup de bizarreries. Par exemple, lorsque vous ajoutez votre middleware Cookie après votre routeur, il est logique que vos itinéraires ne contiennent pas de cookies.
IMHO, la réponse acceptée à cette question n'est pas vraiment précise. Comme d’autres l’ont dit, il s’agit vraiment de contrôler le moment où le prochain gestionnaire de la chaîne est exécuté. Mais je voulais fournir un peu plus de code pour le rendre plus concret. Supposons que vous ayez cette simple application express:
var express = require('express');
var app = express();
app.get('/user/:id', function (req, res, next) {
console.log('before request handler');
next();
});
app.get('/user/:id', function (req, res, next) {
console.log('handling request');
res.sendStatus(200);
next();
});
app.get('/user/:id', function (req, res, next) {
console.log('after request handler');
next();
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});
Si tu fais
curl http://localhost:3000/user/123
vous verrez ceci imprimé à la console:
before request handler
handling request
after request handler
Maintenant, si vous commentez l'appel à next()
dans le gestionnaire du milieu comme ceci:
app.get('/user/:id', function (req, res, next) {
console.log('handling request');
res.sendStatus(200);
//next();
});
Vous verrez ceci sur la console:
before request handler
handling request
Notez que le dernier gestionnaire (celui qui imprime after request handler
) ne s'exécute pas. C'est parce que vous ne dites plus exprès d'exécuter le prochain gestionnaire.
Donc, peu importe si votre gestionnaire "principal" (celui qui renvoie 200) a réussi ou non. Si vous voulez que le reste des middlewares s'exécute, vous devez appeler next()
.
Quand cela serait-il utile? Supposons que vous souhaitiez consigner toutes les demandes reçues dans une base de données, que la demande ait abouti ou non.
app.get('/user/:id', function (req, res, next) {
try {
// ...
}
catch (ex) {
// ...
}
finally {
// go to the next handler regardless of what happened in this one
next();
}
});
app.get('/user/:id', function (req, res, next) {
logToDatabase(req);
next();
});
Si vous voulez que le second gestionnaire s'exécute, vous devez appeler next()
dans le premier gestionnaire.
Rappelez-vous que ce noeud est asynchrone, il ne peut donc pas savoir quand le rappel du premier gestionnaire est terminé. Vous devez le dire en appelant next()
.
next () sans paramètre appelle le prochain gestionnaire d'itinéraire OR le prochain middleware dans le cadre.
Cela signifie simplement que vous passez le contrôle au prochain gestionnaire.
À votre santé
La question portait également sur l’utilisation de next («route») qui semble être couverte la semaine dans les réponses fournies jusqu’à présent:
En bref: la prochaine fonction middleware.
Extrait de cette documentation officielle Documentation Express JS - Page 'write-middleware' :
"La fonction middleware myLogger imprime simplement un message, puis transmet la requête à la fonction middleware next dans la pile en appelant la fonction next ()."
var express = require('express')
var app = express()
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
}
app.use(myLogger)
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.listen(3000)
Cette page de la documentation d'Express JS indique "Si la fonction middleware actuelle ne met pas fin au cycle requête-réponse, elle doit appeler next () pour passer le contrôle à la fonction middleware suivante. Sinon, la requête restera en suspens. "
En bref: route suivante (vs. fonction middleware suivante dans le cas de next ())
Extrait de cette Documentation Express JS - Page 'using-middleware' :
"Pour ignorer le reste des fonctions middleware de la pile de middleware d'un routeur, appelez next (" route ") pour passer le contrôle à la route next. REMARQUE: next (" route ") fonctionnera uniquement dans les fonctions de middleware qui étaient chargé à l'aide des fonctions app.METHOD () ou router.METHOD ().
Cet exemple montre une sous-pile de middleware qui gère les demandes GET dans le chemin/user /: id. "
app.get('/user/:id', function (req, res, next) {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route')
// otherwise pass the control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// render a regular page
res.render('regular')
})
// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
res.render('special')
})