Qual é o parâmetro "next" usado no Express?
app.get('/', function(req, res){
res.send('Hello World');
});
Esta função tem dois parâmetros, req
e res
, que representam os objectos de pedido e resposta, respectivamente.
por outro lado, existem outras funções com um terceiro parâmetro chamado next
. Por exemplo, vamos dar uma olhada no seguinte código:
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?
}
});
não consigo entender qual é o objectivo de next()
ou porque está a ser usado. Nesse exemplo, se id não existe, o que é next
realmente a fazer?
5 answers
Passa o controlo para a próxima via correspondente. No exemplo que você dá, por exemplo, você pode procurar o usuário no banco de dados se um id
foi dado, e atribuí-lo a req.user
.
Abaixo, pode ter uma rota como:
app.get('/users', function(req, res) {
// check for and maybe do something with req.user
});
Uma vez que o /users/123 irá corresponder à rota no seu exemplo primeiro, que irá primeiro verificar e encontrar o utilizador 123
; Depois /users
pode fazer alguma coisa com o resultado disso.
Route middleware (nota: a ligação é para 2.x documentação, mas este é testado como trabalho em 3.x) é uma ferramenta mais flexível e poderosa, no entanto, na minha opinião, uma vez que não depende de um esquema de URI particular ou ordenação de rota. Eu estaria inclinado a modelar o exemplo mostrado assim, assumindo um modelo Users
com um async 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 o fluxo assim é muito útil. Você pode querer ter certas páginas apenas disponíveis para usuários com uma bandeira de administração:
/**
* 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 isto te tenha dado algum inspiração!
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);
next
, você precisa ter uma pequena idéia do ciclo de requisição-resposta no nó, embora não muito em detalhe.
Começa por você fazer um pedido HTTP para um determinado recurso e termina quando você envia uma resposta de volta para o usuário, ou seja, quando você encontrar algo como res. send ('Hello World');
Vejamos um exemplo muito simples.
app.get('/hello', function (req, res, next) {
res.send('USER')
})
Aqui não precisamos do próximo (), porque resp.enviar irá terminar o ciclo e entregar o controle de volta à rota middleware.
Agora vamos dar uma olhada em outro exemplo.app.get('/hello', function (req, res, next) {
res.send("Hello World !!!!");
});
app.get('/hello', function (req, res, next) {
res.send("Hello Planet !!!!");
});
Aqui temos 2 funções de middleware para o mesmo caminho. Mas vais ter sempre a resposta do primeiro. Porque isso é montado primeiro na pilha de middleware e res.send irá terminar o ciclo.
Mas e se sempre não quisermos o " Olá Mundo !!!!"resposta de volta.
Para algumas condições podemos querer o " Hello Planet !!!!" resposta.
Vamos modificar o código acima e ver o que acontecer.
app.get('/hello', function (req, res, next) {
if(some condition){
next();
return;
}
res.send("Hello World !!!!");
});
app.get('/hello', function (req, res, next) {
res.send("Hello Planet !!!!");
});
O que está a fazer aqui? E sim, podes ter gusses. Ele vai saltar a primeira função middleware se a condição for verdadeira e invocar a próxima função middleware e você terá a resposta "Hello Planet !!!!"
.
Então, em seguida passe o controle para a próxima função na pilha de middleware.
E se a primeira função middleware não enviar qualquer resposta, mas executar um pedaço de lógica e então você obter a resposta de volta do segundo middleware funcao.
Algo como em baixo: -
app.get('/hello', function (req, res, next) {
// Your piece of logic
next();
});
app.get('/hello', function (req, res, next) {
res.send("Hello !!!!");
});
Neste caso, é necessário invocar ambas as funções do middleware.
Então, a única maneira de chegar à segunda função middleware é chamando next ();
E se não ligares para o próximo? Não espere que a segunda função middleware seja invocada automaticamente. Depois de invocar a primeira função o seu pedido será deixado pendurado. A segunda função nunca será invocada e você não vai voltar a resposta.
O seguinte é usado para passar o controlo para a próxima função middleware. Se não o pedido será deixado pendurado ou aberto.
Chamando esta função invoca a próxima função middleware na aplicação. A função next () não é uma parte do nó.js ou Express API, mas é o terceiro argumento que é passado para a função middleware. A função next() pode ser chamada de qualquer coisa, mas por convenção é sempre chamada de "next".