2012-05-22 20 views
185

Suponga que tiene un simple bloque de código como este:¿Para qué se usa el parámetro "siguiente" en Express?

app.get('/', function(req, res){ 
    res.send('Hello World'); 
}); 

Esta función tiene dos parámetros, req y res, que representan la solicitud y la respuesta objetos respectivamente.

Por otro lado, hay otras funciones con un tercer parámetro llamado next. Por ejemplo, permite echar un vistazo al código siguiente:

app.get('/users/:id?', function(req, res, next){ // Why do we need next? 
    var id = req.params.id; 
    if (id) { 
     // do something 
    } else { 
     next(); // What is this doing? 
    } 
}); 

No puedo entender lo que el punto de next() es o por qué su ser utilizada. En ese ejemplo, si la identificación no existe, ¿qué está haciendo realmente next?

+6

Siguiente simplemente permite que el siguiente controlador de ruta en línea maneje la solicitud. En este caso, si la identificación del usuario existe, es probable que use 'res.send' para completar la solicitud. Si no existe, es probable que haya otro controlador que emita un error y luego complete la solicitud. –

+1

, entonces dices que tengo 'app.post ('/ login', función (req, res))' después de 'app.get ('/ users', function (req, res))' se llamará login siendo la siguiente ruta en el archivo app.js al llamar a next()? – Menztrual

+2

No, debe consultar esta parte de la documentación de Express.js: http://expressjs.com/guide.html#passing-route control –

Respuesta

198

Pasa el control a la siguiente ruta coincidente. En el ejemplo que da, por ejemplo, puede buscar al usuario en la base de datos si se le dio un id, y asignarlo al req.user.

A continuación, puede tener una ruta como:

app.get('/users', function(req, res) { 
    // check for and maybe do something with req.user 
}); 

Desde/usuarios/123 coincidirá con la ruta en su ejemplo en primer lugar, que primero comprobar y encontrar el usuario 123; entonces /users puede hacer algo con el resultado de eso.

Route middleware (nota: el enlace es a la documentación 2.x, pero esto se ha probado como trabajar en 3.x) es una herramienta más flexible y poderosa, aunque, en mi opinión, ya que no depende de un particular Esquema URI u orden de ruta. Me inclinaría a modelar el ejemplo que se muestra como este, asumiendo un modelo con un Users asíncrono findOne():

function loadUser(req, res, next) { 
    if (req.params.userId) { 
    Users.findOne({ id: req.params.userId }, function(err, user) { 
     if (err) { 
     next(new Error("Couldn't find user: " + err)); 
     return; 
     } 

     req.user = user; 
     next(); 
    }); 
    } else { 
    next(); 
    } 
} 

// ... 

app.get('/user/:userId', loadUser, function(req, res) { 
    // do something with req.user 
}); 

app.get('/users/:userId?', loadUser, function(req, res) { 
    // if req.user was set, it's because userId was specified (and we found the user). 
}); 

// Pretend there's a "loadItem()" which operates similarly, but with itemId. 
app.get('/item/:itemId/addTo/:userId', loadItem, loadUser, function(req, res) { 
    req.user.items.append(req.item.name); 
}); 

ser capaz de controlar el flujo de este tipo es bastante práctico. Es posible que desee tener ciertas páginas solamente disponible para los usuarios con una bandera de administración:

/** 
* Only allows the page to be accessed if the user is an admin. 
* Requires use of `loadUser` middleware. 
*/ 
function requireAdmin(req, res, next) { 
    if (!req.user || !req.user.admin) { 
    next(new Error("Permission denied.")); 
    return; 
    } 

    next(); 
} 

app.get('/top/secret', loadUser, requireAdmin, function(req, res) { 
    res.send('blahblahblah'); 
}); 

espero que esto le dio un poco de inspiración!

+0

por lo que solo reduce una tonelada de código en la única ruta? – Menztrual

+0

¡Podrías decir eso! Sin embargo, estaría más inclinado a hacer este tipo de cosas con [middleware de ruta] (http://expressjs.com/guide.html#route-middleware), ya que no relaciona la lógica con un orden particular de rutas, o estructuras particulares de URI. – Ashe

+0

El enlace "middleware de ruta" parece estar roto (el sufijo # no tiene ningún efecto), ¿puedes arreglarlo? – djechlin

46

También tuve problemas para entender siguiente(), pero this ayudó

var app = require("express")(); 

app.get("/", function(httpRequest, httpResponse, next){ 
    httpResponse.write("Hello"); 
    next(); //remove this and see what happens 
}); 

app.get("/", function(httpRequest, httpResponse, next){ 
    httpResponse.write(" World !!!"); 
    httpResponse.end(); 
}); 

app.listen(8080); 
+2

¡Muy breve! ¡Gracias! Pero, ¿cómo asegurarse de que se llame al primer '.get' y no al 2º? – JohnnyQ

+8

@JohnnyQ Será la ejecución de arriba hacia abajo – Tapash

4

siguiente se utiliza para pasar el control a la siguiente función de middleware. Si no, la solicitud se dejará pendiente o abierta.

+1

No estoy seguro de lo que esta respuesta agrega a una pregunta de casi siete años ... – mherzig

+0

Aunque breve, este comentario me llevó a esto: https://expressjs.com /es/guia/escritura-middleware.html – hmak

0

Llamar a esta función invoca la siguiente función de middleware en la aplicación. La función next() no forma parte de la API Node.js o Express, pero es el tercer argumento que se pasa a la función de middleware. La función next() podría llamarse cualquier cosa, pero por convención siempre se llama "next".

Cuestiones relacionadas